Dans ASP.NET Core, le cadre d'injection de dépendances de Microsoft vous permet notamment de est lié aux "génériques ouverts". (types génériques non liés à un type concret) comme suit :
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton(typeof(IRepository<>), typeof(Repository<>))
}
Vous pouvez également employer le modèle d'usine pour hydrater les dépendances . Voici un exemple artificiel :
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()
);
}
Cependant, je n'ai pas réussi à trouver le moyen de combiner les deux concepts. Il semble que cela pourrait commencer par quelque chose comme ceci, mais j'ai besoin du type concret qui est utilisé pour hydrater une instance de 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();
}
);
}
Si j'essaie d'utiliser le Func<IServiceProvider, object>
avec un générique ouvert, j'obtiens ce ArgumentException
avec le message Open generic service type 'IRepository<T>' requires registering an open generic implementation type.
à partir de l'interface CLI de Dotnet. Il n'arrive même pas à la lambda.
Ce type de liaison est-il possible avec le cadre d'injection de dépendances de Microsoft ?