2017-02-16 144 views
1

我使用OWIN中間件(所以使用startup.cs代替global.asax)在我的ASP.NET MVC 5 Web應用程序中連接Autofac依賴注入,並嘗試使用屬性注入在Controller中設置一個公共變量。在構造函數中注入屬性值爲空

我玩弄屬性注入讓Autofac自動在LoginController中設置Test屬性。

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'公共屬性總是爲空,因此會在運行時中斷。

任何想法可能是我的問題?感謝您的幫助! :)

+2

可能的重複[如何使用AutoFac注入屬性?](http://stackoverflow.com/questions/15600440/how-to-use-property-injection-with-autofac) – Steve

+0

我想你有你的註冊錯誤的方式。控制器需要應用'PropertiesAutowired',而不是依賴項。 – Steve

+0

您需要將您的Test對象傳遞給構造函數,或者不要在構造函數中使用此對象。在執行構造函數之前,不能分配屬性。 – trailmax

回答

5

因此,'測試'公共屬性始終爲空,因此在運行時中斷。

它並不總是爲空。它在構造函數中爲空,因爲Autofac(實際上是所有代碼)在構造函數爲完成之前無法設置屬性。

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

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

超級空置下來autofac的版本不一樣的東西:

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

如果需要執行代碼的屬性設置,你可以做一些哈克這樣(但之後你真的應該只是是使用構造器注入):

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

啊,謝謝Erik!沒有意識到測試將在構造函數完成後設置。我現在看到這個工作。我想我應該去。謝謝! –