В ASP.NET Core, одна из вещей, которые вы можете сделать с каркасом Microsoft в зависимости инжекционного is bind "open generics" (общие типы несвязанный к конкретному типу), как так:Factory Pattern с открытым Дженерики
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton(typeof(IRepository<>), typeof(Repository<>))
}
Вы также можете нанимать the factory pattern to hydrate dependencies. Вот надуманный пример:
public interface IFactory<out T> {
T Provide();
}
public void ConfigureServices(IServiceCollection services) {
services.AddTransient(typeof(IFactory<>), typeof(Factory<>));
services.AddSingleton(
typeof(IRepository<Foo>),
p => p.GetRequiredService<IFactory<IRepository<Foo>>().Provide()
);
}
Однако, я не мог понять, как совместить эти два понятия вместе. Похоже, что это начнется с чего-то подобного, но мне нужен конкретный тип, который используется для гидратации экземпляра IRepository<>
.
public void ConfigureServices(IServiceCollection services) {
services.AddTransient(typeof(IFactory<>), typeof(Factory<>));
services.AddSingleton(
typeof(IRepository<>),
provider => {
// Say the IServiceProvider is trying to hydrate
// IRepository<Foo> when this lambda is invoked.
// In that case, I need access to a System.Type
// object which is IRepository<Foo>.
// i.e.: repositoryType = typeof(IRepository<Foo>);
// If I had that, I could snag the generic argument
// from IRepository<Foo> and hydrate the factory, like so:
var modelType = repositoryType.GetGenericArguments()[0];
var factoryType = typeof(IFactory<IRepository<>>).MakeGenericType(modelType);
var factory = (IFactory<object>)p.GetRequiredService(factoryType);
return factory.Provide();
}
);
}
Если я пытаюсь использовать Func<IServiceProvider, object>
функтор с открытым общим, я получаю this ArgumentException
с сообщением Open generic service type 'IRepository<T>' requires registering an open generic implementation type.
из CLI Dotnet. Он даже не добирается до лямбды.
Возможно ли такое связывание с каркасом внедрения зависимостей Microsoft?
Что такое преимущество registerin g лямбда, которая разрешает фабрику, которая разрешает требуемую услугу? – Steven
Хороший вопрос. Он перенаправляет сложность условной гидратации. Вам не нужна явная фабрика, поскольку лямбда действует как одна (ее переменная даже называется «реализацияFactory»), но если вам нужно несколько служб, чтобы принять решение о том, какой экземпляр вы хотите увлажнить, вы будете иметь лямбда, сложная и трудная для тестирования. Сообщение в блоге, приведенное выше, имеет хороший пример: http://dotnetliberty.com/index.php/2016/05/09/asp-net-core-factory-pattern-dependency-injection/ – Technetium
Вы когда-нибудь находили хорошее Ответ для этого? У меня такая же проблема, но ни один из ответов здесь не является хорошим решением проблемы. –