2017-02-16 51 views
1

Я подключаю инъекцию зависимостей Autofac в своем веб-приложении ASP.NET MVC 5 с использованием промежуточного программного обеспечения OWIN (так что используйте startup.cs вместо global.asax) и пытаюсь использовать вложение свойств в установите общедоступную переменную в контроллере.Введенное значение свойства имеет значение null в конструкторе

Я играю с инъекцией свойств, чтобы Autofac автоматически установил свойство Test в LoginController.

public interface ITest 
{ 
    string TestMethod(); 
} 

public class Test : ITest 
{ 
    public string TestMethod() 
    { 
     return "Hello world!"; 
    } 
} 

public class LoginController : Controller 
{ 
    public ITest Test { get; set; } 

    public LoginController() 
    { 
     var aaa = Test.TestMethod(); 

     // Do other stuff... 
    } 
} 

Вот как выглядит мой startup.cs. Я играю вокруг, поэтому некоторые из этого кода могут не понадобиться (или вызвать мою проблему?).

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var builder = new ContainerBuilder(); 
     builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired(); 
     builder.RegisterType<Test>().As<ITest>().SingleInstance(); 
     builder.Register(c => new Test()).As<ITest>().InstancePerDependency(); 

     builder.RegisterType<ITest>().PropertiesAutowired(); 
     builder.RegisterType<LoginController>().PropertiesAutowired(); 

     builder.RegisterModelBinderProvider(); 
     builder.RegisterFilterProvider(); 

     var container = builder.Build(); 

     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

     app.UseAutofacMiddleware(container); 

     AreaRegistration.RegisterAllAreas(); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 

     // Some other stuff... 
    } 
} 

Таким образом, общедоступное свойство «Test» всегда имеет значение null и, следовательно, прерывает выполнение.

Любые идеи, что может быть моей проблемой? Спасибо заранее за вашу помощь! :)

+2

Возможный дубликат [Как использовать вложение свойств с помощью AutoFac?] (Http://stackoverflow.com/questions/15600440/how-to-use-property-injection-with-autofac) – Steve

+0

Я думаю, что у вас есть регистрации неправильного пути. Контроллеру требуется «PropertiesAutowired», а не зависимость. – Steve

+0

Вам либо нужно передать объект Test в конструктор, либо не использовать этот объект внутри конструктора. Свойства не могут быть назначены до выполнения конструктора. – trailmax

ответ

5

Итак, общедоступное свойство «Test» всегда равно null и, следовательно, прерывает выполнение.

Это не всегда null. Он имеет значение null в конструкторе, потому что Autofac (фактически код ALL) не может устанавливать свойства до тех пор, пока конструктор не закончит .

public class LoginController : Controller 
{ 
    public ITest Test { get; set; } 

    public LoginController() 
    { 
     // Test is null, will always be null here 
     var aaa = Test.TestMethod(); 
    } 
} 

супер dummied вниз версия autofac делает что-то вроде:

var controller = new LoginController(); 
controller.Test = new Test(); 

Если вам нужно выполнить код после того, как свойство установлено вы могли бы сделать что-то Hacky как следующее (но на самом деле вы должны просто быть с помощью инъекции конструктора):

public class LoginController : Controller 
{ 
    private ITest _test; 
    public ITest Test 
    { 
     get { return _test; } 
     set 
     { 
     var initialize = (_test == null); 
     _test = value; 
     if (initialize) 
     { 
      Initialize(); 
     } 
     } 
    } 

    public LoginController() 
    { 
    } 

    private void Initialize() 
    { 
     var aaa = Test.TestMethod(); 
    } 
} 

Опять же более логичным способом было бы просто сделать:

public class LoginController : Controller 
{ 
    private readonly ITest _test; 

    public LoginController(ITest test) 
    { 
     _test = test; 
     var aaa = _test.TestMethod(); 

     // Do other stuff... 
    } 
} 
+0

Ах, спасибо Эрик! Не понял, что тест будет установлен после завершения конструктора. Я вижу, что это работает сейчас. Думаю, я должен идти. Спасибо! –