Можем ли мы разрешить реализацию интерфейса, использующего другие реализации интерфейса с помощью Lamar в .NET Core 3?
Я использую.NET Core 3.0 и имею следующие классы
public class DataProviderA: IDataProvider { }
public class DataProviderB: IDataProvider { }
public class DataProviderCombined: IDataProvider {
public DataProviderCombined(IDataProvider providerA, IDataProvider providerB) { ... }
}
В моем Startup.cs у меня зарегистрированы следующие службы:
services.AddTransient<IDataProvider, DataProviderCombined>();
services.ForConcreteType<DataProviderCombined>().Configure.Scoped()
.Ctor<IDataProvider>("providerA").Is<DataProviderA>().Transient()
.Ctor<IDataProvider>("providerb").Is<DataProviderB>().Transient();
Кажется, это не решается должным образом, поскольку я получаю следующие ошибки:
Lamar.IoC.LamarException: не удается создать зарегистрированный экземпляр dataProvider из 'IDataProvider': обнаружены двунаправленные зависимости:
Есть ли часть регистрации, которую мне не хватает в Lamar, чтобы сделать это в.NET Core 3?
1 ответ
Я неправильно понял services.ForConcreteType<> и то, как его использовать, и использовал его неправильно.
Таким образом, с указанным выше DataProviderCombined можно было бы использовать в контроллере, но со сквозной инъекцией конструктора с использованием IDataProvider. Это бы никогда не сработало, потому что регистрация производилась через реализацию, а не через интерфейс.
В итоге было сделано следующее:
services.For<IDataProvider>().Add<DataProviderA>().Named("DA");
services.For<IDataProvider>().Add<DataProviderB>().Named("DB");
services.For<IDataProvider>().Add<CombinedDataProvider>()
.Ctor<IDataProvider>("daProvider").Is<DataProviderA>()
.Ctor<IDataProvider>("dbProvider").Is<DataProviderB>()
.Named("Combined");
services.ForConcreteType<DataController>().Configure
.Scoped()
.Ctor<IDataProvider>("combinedDataProvider")
.IsNamedInstance("Combined");
Это позволило мне использовать комбинированный поставщик данных в конструкторе, используя следующее:
public class DataController {
public DataController(IDataProvider combinedDataProvider) { ... }
}