Je ne sais pas comment formuler cette question, car je ne sais pas où se situe le problème. Je pense que c'est un problème de covariance générique, mais la solution pourrait être trouvée ailleurs, peut-être dans la façon dont les interfaces sont conçues, ou dans la façon dont les implémentations sont enregistrées.Enregistrement automatique et résolution des types implémentant un interace générique
Quoi qu'il en soit, l'échantillon tente d'enregistrer tous les types implémentant une interface générique, puis de résoudre le type en utilisant le type du générique. Ensuite, essayez de convertir ce type en son type de base pour pouvoir appeler une méthode sur cette implémentation.
Son échec maintenant en essayant de lancer. A titre d'exemple, la première ligne de code ne parvient pas à compiler. Une fois supprimé, le programme échoue sur la ligne essayant de lancer l'implémentation.
class Program
{
private static IContainer _container;
static void Main(string[] args)
{
// Is this the problem?
IHandler<IConfiguration> test = new MyHandler();
// setup ioc
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
//.Where(t => typeof(IHandler<IConfiguration>).IsAssignableFrom(t));
.Where(t => t.GetInterfaces()
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHandler<>))
.Any()
)
.As(t => t.GetInterfaces()
.Where(i => i.GetGenericTypeDefinition() == typeof(IHandler<>))
.Single()
);
_container = builder.Build();
// get my configuration impl
var configuration = new MyConfiguration();
// resolve handler for the configuration
var configurationType = configuration.GetType();
var handlerGenericType = typeof(IHandler<>);
var handlerType = handlerGenericType.MakeGenericType(configurationType);
var handler = _container.Resolve(handlerType);
var typedHandler = (IHandler<IConfiguration>) handler;
// handle it!
typedHandler.Handle(configuration);
}
}
public interface IConfiguration
{
}
public interface IHandler<T> where T : IConfiguration
{
void Handle(T myConfiguration);
}
public class MyConfiguration : IConfiguration
{
}
public class MyHandler : IHandler<MyConfiguration>
{
public void Handle(MyConfiguration myConfiguration)
{
Console.WriteLine("Handling my stuff...");
}
}
Essayé cela, et il ne fonctionne toujours pas. Essayé T également, puis l'attribution fonctionne, mais pas l'implémentation du gestionnaire ne compilera pas. – MatteS
@MatteS: Vous avez raison. Veuillez voir la réponse mise à jour. –
Merci beaucoup, maintenant c'est complètement clair pour moi pourquoi cela ne marche pas. Je pense qu'il faut repenser mon design. Ou sinon, c'est peut-être faisable d'appeler mon gestionnaire en utilisant la réflexion. – MatteS