2009-07-27 5 views
28

Étant donné le code suivant, comment puis-je résoudre le problème SomeInstance dans autofac?Résolution de l'interface générique avec Autofac

public class BaseClass {} 

public class SubClass1 : BaseClass {} 

public class SubClass2 : BaseClass {} 

public interface IGenericInterface<T> where T : BaseClass {} 

public class SomeInstance1<T> : IGenericInterface<T> where T : SubClass1 

public class SomeInstance2<T> : IGenericInterface<T> where T : SubClass2 

Je veux choisir SomeInstance1 ou 2 en fonction du type de générique sur les sous-classes. Donc, par exemple, j'ai une collection de sous-classes (SubClass1, 2 ....) et en itérant sur eux, je veux choisir la bonne classe SomeInstance.

Répondre

59

Autofac prend en charge les génériques ouverts. Vous pouvez utiliser le code suivant si génériques type est connu au moment de la compilation:

var builder = new ContainerBuilder(); 

builder.RegisterGeneric(typeof(SomeInstance1<>)) 
    .As(typeof(IGenericInterface<>));    

var container = builder.Build(); 

var instance1 = container.Resolve<IGenericInterface<SubClass1>>(); 

Assert.IsInstanceOfType(typeof(SomeInstance1<SubClass1>), instance1); 

Si le paramètre de type n'est pas connu avant l'exécution (ce qui est probablement votre cas si vous voulez itérer collection de types), vous pouvez construire votre type en utilisant MakeGenericType:

 var typeInRuntime = typeof (SubClass1); 
     var instance1 = container.Resolve(typeof(IGenericInterface<>).MakeGenericType(typeInRuntime)); 
1

Correction. Vous ne pouvez pas appeler MakeGenericType à partir du conteneur. J'ai résolu le problème de l'instanciation des génériques en utilisant 'TYPE' comme paramètre dans l'appel Resolve. Le constructeur est enregistré. Puis la résolution se passe comme ceci, en passant un TypedParameter à la Resolve. Dans ce cas, j'ai une liste d'éléments (IItem) qui sont résolus que je veux créer un référentiel pour tous les éléments de ce type.

 var items = container.Resolve<IEnumerable<IItem<string>>>(); 
     foreach (var item in items) 
     { 
      var repository = container.Resolve(typeof (IRepository<DataItemBase>), new TypedParameter(item.GetType(), item)); 
      Assert.IsNotNull(repository); 
     } 

Merci pour votre message, il a aidé et j'espère que cette mise à jour aide.

Questions connexes