5

我可以在 MVC Core 中轻松使用构造函数参数注入。但是不支持属性注入。我尝试使用 AutoFac 但也失败了。
那么如何在 MVC Core 中使用属性注入。
这是 AutoFac 的代码

services.AddMvc();
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Test2>().As<ITest>();
builder.RegisterType<HomeController>().PropertiesAutowired();
builder.Populate(services);
var container = builder.Build();
//The following code works
HomeController test2 = container.Resolve<HomeController>();
return new AutofacServiceProvider(container); 
4

2 回答 2

3

在 dotnet core 中,您需要进行以下更改才能使 Autofac 工作:IContainer在您的应用程序中添加公共 AutofacStartup.cs

public IContainer ApplicationContainer { get; private set; }

更改ConfigureServicesStartup.csreturn IServiceProvider,完成所有注册,使用 . 填充容器中的框架服务builder.Populat(services);。请注意,您无需这样做builder.RegisterType<HomeController>().PropertiesAutowired();

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    builder.Populate(services);
    ApplicationContainer = container;
    return new AutofacServiceProvider(ApplicationContainer);
}

您还需要确保通过在您的Configure方法中执行此操作来处理已停止的应用程序上的容器。

public void Configure(IApplicationBuilder app, IApplicationLifetime appLifetime)
{
    app.UseMvc();           
    appLifetime.ApplicationStopped.Register(() => ApplicationContainer.Dispose());
}

完成此操作后 - 您的控制器应自动获取自动装配的属性。

于 2018-05-23T17:43:28.093 回答
2

属性注入需要一些额外的设置。让我们假设在您的情况下,我们有这个类层次结构:

    public class HomeController 
    {
        public ITest Test {get; set;}            
    }    
    public class Test : ITest
    {
        public IRepository Repository {get;set;}    
    }
    public class Repository: IRepository
    {
    }

需要做的第一件事是将返回类型更改为 IServiceProvider并使用“Autofac.Extensions.DependencyInjection”方法中的方法ConfigureServices(IServiceCollection services)构建新容器,以返回 AutofacServiceProviderPopulate

新的 ConfigureServices 方法:

public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().AddControllersAsServices();
        ContainerBuilder builder = new ContainerBuilder();

        builder.Populate(services);//Autofac.Extensions.DependencyInjection

        /*Here we are going to register services for DI*/

        return new AutofacServiceProvider(builder.Build());
    }

下一步是在 DI 容器中注册类。“服务类”的属性注入比“控制器”需要更少的操作。要为服务类设置属性注入,您只需要:

  1. 在容器中注册类型: builder.RegisterType<Repository>().As<IRepository>();
  2. 使用PropertiesAutowired()注册您将通过属性注入依赖项的类型: builder.RegisterType<Test>.As<ITest>().PropertiesAutowired()

要为控制器设置属性注入,您需要更多步骤:

  1. 执行AddControllersAsServices()时间services.AddMvc()
  2. 为所有控制器调用的控制器注册 DI PropertiesAutowired()

    //in case you just need to allow registration for several specific controllers change this line
    var controllersTypesInAssembly = typeof(Startup).Assembly
            .GetExportedTypes()
            .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
    
    builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired(); 
    

因此,这里是用于预定层次结构的 ConfigureServices():

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddControllersAsServices();
    ContainerBuilder builder = new ContainerBuilder();

    builder.Populate(services);//Autofac.Extensions.DependencyInjection

    builder.RegisterType<Repository>().As<IRepository>()
        .InstancePerLifetimeScope();
    var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
        .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();

    builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
    builder.RegisterType<Test>().As<ITest>().PropertiesAutowired();
    return new AutofacServiceProvider(builder.Build());
}
于 2018-12-31T14:15:31.983 回答