In ASP.NET Core, one of the things you can do with Microsoft's dependency injection framework is bind "open generics" (generic types unbound to a concrete type) like so:
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton(typeof(IRepository<>), typeof(Repository<>))
}
You can also employ the factory pattern to hydrate dependencies. Here's a contrived example:
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()
);
}
However, I have not been able to figure out how to combine the two concepts together. It seems like it would start with something like this, but I need the concrete type that is being used to hydrate an instance of 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();
}
);
}
If I try to use the Func<IServiceProvider, object>
functor with an open generic, I get this ArgumentException
with the message Open generic service type 'IRepository<T>' requires registering an open generic implementation type.
from the dotnet CLI. It doesn't even get to the lambda.
Is this type of binding possible with Microsoft's dependency injection framework?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…