在ASP.NET核心,你可以用微軟的依賴注入框架做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>
函子以開放通用的,我得到this ArgumentException
從DOTNET CLI消息Open generic service type 'IRepository<T>' requires registering an open generic implementation type.
。它甚至沒有達到拉姆達。
這種類型的綁定可能與微軟的依賴注入框架?
registerin的優點是什麼g解析解決所需服務的工廠的lambda表達式? – Steven
好問題。它改變了條件水合的複雜性。你不需要一個明確的工廠,因爲lambda作爲一個(它的變量甚至稱爲「implementationFactory」),但是如果你需要幾個服務來決定你想要保存什麼樣的實例,你將會擁有一個複雜且難以測試的lambda。該博客文章中,我上面鏈接有一個很好的例子:http://dotnetliberty.com/index.php/2016/05/09/asp-net-core-factory-pattern-dependency-injection/ – Technetium
你有沒有找到一個很好的爲此回答?我有同樣的問題,但這裏沒有一個答案似乎是解決問題的好方法 –