2012-05-02 8 views
2

Je suis en train d'apprendre Autofac et d'essayer de comprendre comment résoudre les dépendances entre les services.Autofac: Enregistrer des classes qui dépendent d'instances spécifiques d'autres classes

Dire que j'ai les classes suivantes:

class ClassA {} 
class ClassB {} 
class ClassC {} 

class Classes 
{ 
    public Classes(ClassA classA, ClassB classB, ClassC classC) 
    { 
     ... 
    } 
} 

et que je veux enregistrer les classes afin qu'il imite le comportement ci-dessous.

var classA1 = new ClassA("A1"); 
var classB1 = new ClassB("B1"); 
var classC1 = new ClassC("C1"); 
var classes1 = new Classes(classA1, classB1, classC1); 

var classA2 = new ClassA("A2"); 
var classB2 = new ClassB("B2"); 
var classC2 = new ClassC("C2"); 
var classes2 = new Classes(classA2, classB2, classC2); 

En bref, Classes dépend de cas spécifiques de ClassA, ClassB et ClassC. Comment je fais ça?

Répondre

4

Si vous vouliez créer plusieurs instances uniques de la classe Classes, je construirais mon enregistrement en utilisant la fonctionnalité parameter passing d'Autofac. Mon code ressemblerait à quelque chose comme

var builder = new ContainerBuilder(); 
builder.Register((c,p) => new ClassA(p.Named<string>("a"))); 
builder.Register((c,p) => new ClassB(p.Named<string>("b"))); 
builder.Register((c,p) => new ClassC(p.Named<string>("c"))); 
builder.Register((c,p) => new Classes(
    c.Resolve<ClassA>(new NamedParameter("a", p.Named<string>("ClassA"))), 
    c.Resolve<ClassB>(new NamedParameter("b", p.Named<string>("ClassB"))), 
    c.Resolve<ClassC>(new NamedParameter("c", p.Named<string>("ClassC"))))); 

var container = builder.Build(); 
var classes = container.Resolve<Classes>(
    new NamedParameter("ClassA", "AAAA"), 
    new NamedParameter("ClassB", "BBBB"), 
    new NamedParameter("ClassC", "CCCCC")); 

Les trois premiers appels de registre disent Autofac que quand il veut construire une instance de ClassA (ou B ou C), il doit utiliser extraire la valeur d'une instance de NamedParameter avec nom de "a" (ou "b" ou "c") et transmettre cette valeur au constructeur de ClassA. L'objet NamedParameter sera transmis dans le cadre de l'appel Resolve, comme Resolve<ClassA>(new NamedParameter("a", "AAAA")). L'appel de registre final indique à Autofac qu'il doit résoudre une instance de ClassA, ClassB et ClassC et transmettre ces instances au constructeur de Classes. Pour résoudre ces dépendances, Autofac doit extraire des valeurs de certaines instances de NamedParameter qui ont été transmises et les transmettre dans Resolve dans les nouvelles instances NamedParameter.

Deux choses à noter.

  1. Il peut être possible de réutiliser les instances NamedParameter dans l'appel Register for Classes au lieu d'en créer de nouvelles. Le paramètre p de la fonction anonyme est un IEnumerable, donc cela pourrait être possible.
  2. Ce code a été testé en utilisant la dernière version d'Autofac (2.6.1).
+0

Je n'ai pas fini par résoudre exactement comme ça, mais grâce à vos pointeurs j'ai réussi à le travailler à l'aide 'RegisterType () .Named (« ClassA »)', puis 'Inscrivez ((c, p) => nouvelles classes (c.ResolveNamed ("ClassA"))) '. Merci! –

2

La méthode la plus simple consiste à utiliser des étendues de durée de vie. Enregistrez vos classes comme ceci:

builder.RegisterType<ClassA>().InstancePerLifetimeScope(); 
builder.RegisterType<ClassB>().InstancePerLifetimeScope(); 
builder.RegisterType<ClassC>().InstancePerLifetimeScope(); 

Et que de créer un champ à vie comme ceci:

var scope = container.BeginLifetimeScope(); 

Maintenant, vous pouvez résoudre les cas de scope comme du récipient, mais chaque champ a une instance distincte de ClassA, ClassB et ClassC.

Questions connexes