【问题标题】:Property injected value is null in constructor构造函数中的属性注入值为 null
【发布时间】:2017-02-16 23:37:56
【问题描述】:

我正在使用 OWIN 中间件(因此使用 startup.cs 而不是 global.asax)在我的 ASP.NET MVC 5 Web 应用程序中连接 Autofac 依赖注入,并尝试使用属性注入在控制器中设置公共变量.

我正在使用属性注入让 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”公共属性始终为 null,因此会在运行时中断。

有什么想法可能是我的问题吗?提前感谢您的帮助! :)

【问题讨论】:

  • 我认为您的注册方式有误。控制器需要应用PropertiesAutowired,而不是依赖项。
  • 您要么需要将 Test 对象传递给构造函数,要么不要在构造函数中使用该对象。在构造函数执行之前不能分配属性。
  • @Steve,谢谢你,我会试一试的。
  • @trailmax,是的,你是对的,直到构造函数运行后才会设置属性。

标签: c# dependency-injection autofac property-injection


【解决方案1】:

因此,“Test”公共属性始终为 null,因此会在运行时中断。

它并不总是为空。它在构造函数中为 null,因为 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...
    }
}

【讨论】:

  • 啊,谢谢埃里克!没有意识到在构造函数完成后会设置测试。我现在看到这个工作。我想我该走了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多