Как разрешить зависимость с помощью метаданных потребляющего класса - PullRequest
0 голосов
/ 10 июля 2020

Настройка приведена ниже, я хочу, чтобы IDependency, используемый Service, создавался с attachedToClassName = nameof(Service) или действительно с фактическим именем класса, потребляющим IDependency.

Я не могу изменить конструкторы / интерфейсы, ищу решение, работающее с. NET Core DI (без боковых библиотек).

public class OtherDependency: IOtherDependency
{
  
}

public class Dependency: IDependency
{
   public Dependency(IOtherDependency otherDependency, string attachedToClassName) {...}
}

public class Service
{
   // 
   public Service(IDependency dependency)
   {
      
   }    
}

1 Ответ

0 голосов
/ 10 июля 2020

лучший подход будет таким же. net основных применений для ILogger -> введение обобщенного типа c. Это означает, что вам следует менять свои интерфейсы, а вы этого не хотите.

Давайте погрузимся в сложный.

Нам нужно взглянуть на этот метод:

 ObjectFactory ActivatorUtilitiess.CreateFactory(Type, Type[]) 

https://docs.microsoft.com/it-it/dotnet/api/microsoft.extensions.dependencyinjection.activatorutilities.createfactory?view=dotnet-plat-ext-3.1

Этот метод возвращает фабрику объектов для типа, указанного в качестве первого параметра. ObjectFactory является делегатом:

public delegate object ObjectFactory(IServiceProvider serviceProvider, object[] arguments);

https://docs.microsoft.com/it-it/dotnet/api/microsoft.extensions.dependencyinjection.objectfactory?view=dotnet-plat-ext-3.1

, чем нам также нужна эта перегрузка IServiceCollection.AddSingleton (или любое время жизни)

 public static IServiceCollection AddSingleton(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> factory)

в Startup.ConfigureServices вы должны сделать следующее:

 var objFactory1 = ActivatorUtilities.CreateFactory(typeof(Dependency1), new Type[]{typeof(string)});
 var objFactory2 = ActivatorUtilities.CreateFactory(typeof(Dependency2), new Type[]{typeof(string)});
 //and so on for all your concrete dependencies

 var serviceObjFactory1 = ActivatorUtilities.CreateFactory(typeof(Service1), new Type[] {typeof(IDependency)});

 services.AddSingleton(typeof(Service1),sp => serviceObjFactory1(sp, new object[] {
     objFactory1(sp, new object[]{"attached for Service1"})
 });

с фабрикой объектов вы создаете экземпляр класса, который извлекает все зависимости от поставщика услуг, кроме зависимостей типов, которые вы указали при создании фабрика. Эти экземпляры зависимостей должны быть указаны при вызове фабрики

...