Как использовать свойство Injection в MVC Core и AutoFac - PullRequest
0 голосов
/ 23 мая 2018

Я легко могу использовать инжектор параметров конструктора в MVC Core.Но Property Injection не поддерживается. Я пытаюсь использовать AutoFac, но тоже не получается.
Итак, как использовать Property Injection в 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); 

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Внедрение свойства требует дополнительной настройки.Предположим, что в вашем случае у нас есть эта иерархия классов:

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

Прежде всего необходимо изменить тип возвращаемого значения на IServiceProvider для ConfigureServices(IServiceCollection services) и построить новый контейнер, используя метод Populate из 'Метод Autofac.Extensions.DependencyInjection 'для возврата AutofacServiceProvider

Новый метод 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. Regiser 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());
}
0 голосов
/ 23 мая 2018

В ядре dotnet необходимо внести следующие изменения, чтобы заставить Autofac работать: Добавить общедоступный Autofac IContainer в ваше приложение Startup.cs

public IContainer ApplicationContainer { get; private set; }

Изменить ConfigureServices в Startup.cs наверните 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());
}

После того, как вы это сделаете - ваши контроллеры должны автоматически получить свойства автоматически подключенными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...