2011-03-05 3 views
0

débutants Question: Étant donné deux classes: Myclass5 et Myclass6 comment peut un fil méthode jusqu'à en sortie d'usine (retourné comme Func) telle que myclass5 et myclass6 instances et IMyClass qu'ils dépendent sont tous récupérés par l'intermédiaire autofac (en supposant que ces trois instances sont enregistrées).Autofac question de câblage - débutants

public static MyClass4 FactoryMethod(int nu) 
    { 
     if (nu == 1) 
      return new MyClass5(....); 
     if (nu == 4) 
      return new MyClass6(....); 

     throw new NotImplementedException(); 
    } 

public abstract class MyClass4 
{ 

} 

public class MyClass5 : MyClass4 
{ 
    public MyClass5(int nu, IMyClass a) 
    { 

    } 
} 

public class MyClass6 : MyClass4 
{ 
    public MyClass6(int nu, IMyClass a) 
    { 

    } 
} 

Répondre

3

Pour FactoryMethod pour pouvoir créer les cas, il faut avoir accès à un conteneur. Je suggère de créer un type de délégué pour la méthode d'usine, ce qui le rend facile à prendre en dépendance. L'inscription se présente comme suit:

var cb = new ContainerBuilder(); 
cb.RegisterType<SomeClass>().As<IMyClass>(); 
cb.RegisterType<MyClass5>(); 
cb.RegisterType<MyClass6>(); 
cb.Register((c, p) => 
    { 
     var context = c.Resolve<IComponentContext>(); 
     return new FactoryMethod(nu => 
      { 
       var nuParameter = TypedParameter.From(nu); 
       switch (nu) 
       { 
        case 1: 
         return context.Resolve<MyClass5>(nuParameter); 
        case 4: 
         return context.Resolve<MyClass6>(nuParameter); 
        default: 
         throw new NotImplementedException(); 
       } 
      }); 
     }); 

var container = cb.Build(); 

Au moment de la détermination, vous pouvez alors prendre une dépendance du type de délégué FactoryMethod et l'utiliser pour résoudre les cas:

var factory = container.Resolve<FactoryMethod>(); 
var instance5 = factory(1); 
var instance6 = factory(1); 

Note: l'instance de délégué que nous créons a besoin d'un contexte. Nous ne pouvons pas utiliser directement le paramètre c puisque ce contexte est seulement temporaire. Ainsi, nous devons résoudre un IComponentContext pour "faire cuire" dans le lambda.

Mise à jour: si vous souhaitez extraire la mise en œuvre de l'usine dans une méthode qui ne dépend pas du conteneur je suggère ce qui suit:

public class FactoryMethodImpl 
    { 
     readonly Func<int, MyClass5> _factory5; 
     readonly Func<int, MyClass6> _factory6; 

     public FactoryMethodImpl(Func<int, MyClass5> factory5, Func<int, MyClass6> factory6) 
     { 
      _factory5 = factory5; 
      _factory6 = factory6; 
     } 

     public MyClass4 Create(int nu) 
     { 
      switch (nu) 
      { 
       case 1: 
        return _factory5(nu); 
       case 4: 
        return _factory6(nu); 
       default: 
        throw new NotImplementedException(); 
      } 
     } 
    } 

Maintenant, changer le code d'enregistrement à ceci:

var cb = new ContainerBuilder(); 
cb.RegisterType<SomeClass>().As<IMyClass>(); 
cb.RegisterType<MyClass5>(); 
cb.RegisterType<MyClass6>(); 
cb.RegisterType<FactoryMethodImpl>().SingleInstance(); 
cb.Register(c=> new FactoryMethod(c.Resolve<FactoryMethodImpl>().Create)); 
+0

Merci. Il semble que je n'ai pas d'autre choix que de créer le type FactoryMethod. Mais je voudrais que cette méthode d'usine fasse partie de mon code mais si je fais cela alors je devrais porter Autofacs IComponentContext dans mon code. Tout travail autour de cette situation? – GreatOrdinary

+0

@ user645788: voir ma réponse mise à jour. Je dirais, avec Autofac il y a toujours un choix;) –

+0

merci beaucoup ... c'était trop simple ... gentil – GreatOrdinary