【发布时间】:2016-12-26 01:01:02
【问题描述】:
在 ASP.NET Core 中,您可以使用 Microsoft 的依赖注入框架 is bind "open generics"(未绑定到具体类型的泛型类型)执行以下操作:
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> 函子与开放泛型一起使用,我会从 dotnet CLI 获得带有消息 Open generic service type 'IRepository<T>' requires registering an open generic implementation type. 的 this ArgumentException。它甚至没有到达 lambda。
微软的依赖注入框架可以实现这种类型的绑定吗?
【问题讨论】:
-
注册一个解析所需服务的工厂的 lambda 有什么好处?
-
好问题。它改变了条件水合的复杂性。您不需要显式工厂,因为 lambda 充当一个工厂(它的变量甚至称为“implementationFactory”),但是如果您需要多个服务来决定要水合的实例,您将拥有一个复杂且难以测试的 lambda。我上面链接的博客文章有一个很好的例子:dotnetliberty.com/index.php/2016/05/09/…
-
你有没有找到一个好的答案?我有同样的问题,但这里的答案似乎都不是解决问题的好方法
-
我们通过在服务注册前关闭泛型“解决”了这个问题。我把它写在这个 GitHub 问题上。 github.com/aspnet/DependencyInjection/issues/…
-
恕我直言,真正的解决方案是不使用微软的 DI 容器。他们已经声明他们不会在这个 GitHub 线程中解决这个问题。 github.com/aspnet/DependencyInjection/issues/…
标签: c# generics dependency-injection asp.net-core