2010-10-26 10 views
2

Je suis relativement nouveau dans l'injection de dépendance, donc je suis probablement en train de dépeindre le concept dans une certaine mesure. Cependant, j'essaie de réaliser quelque chose comme ce qui suit, mais je ne sais pas si c'est faisable:Injection de dépendances réflexives .NET avec plusieurs conteneurs

Disons que j'ai deux conteneurs, chacun contenant différentes instances du même type de dépendance. Par exemple, chaque contient unique instance de MyApplicationContext et MyRequestContext.

Dites maintenant que j'ai plusieurs classes qui dépendent d'une (ou des deux) de ces instances. Ils ne devraient pas se préoccuper de savoir lequel des deux conteneurs ils utilisent; ils ont simplement besoin d'une instance de la dépendance pour faire le travail.

Dans un monde idéal, chacune de ces classes fiables fait un appel statique dans son constructeur, qui à son tour injecte les dépendances pensivement de un récipient approprié ...

public class MyDependableClass{ 
    protected MyApplicationContext Application {get; set;} 
    protected MyRequestContext Request {get; set;} 
    public MyDependableClass() { 
    Dependencies.Inject(this); 
    } 
} 

Cependant, il n'y a pas autant que je sache façon pratique de déterminer un conteneur approprié. J'ai envisagé d'enregistrer chaque objet sur un conteneur particulier (par exemple container.Register(obj);), mais cela serait laborieux et ne fonctionnerait pas si des dépendances étaient requises dans le constructeur. Vous pouvez également analyser la pile d'appels pour déduire le conteneur d'un objet de niveau supérieur enregistré ... ne fonctionnerait pas pour les appels asynchrones, etc.

Des idées?

Exemple: Je peux avoir plusieurs classes qui peuvent dépendre d'une instance d'un proxy; appelons-le ILogicProxy. Ce proxy peut renvoyer les appels à la logique locale ou distante sur une autre machine. De plus, l'application peut établir des connexions avec plusieurs machines distantes. Donc ... nous avons potentiellement plusieurs instances ILogicProxy qui doivent être injectées dans plusieurs classes ... mais laquelle va où? Une solution comme celle-ci pourrait simplement utiliser une simple 'injection de propriété de setter', mais elle ne sera pas mise à l'échelle lorsque plus de dépendances sont nécessaires, car cela rendrait le processus de 'câblage' plus salissant/bavard.

+1

Pouvez-vous mettre à jour votre question pour expliquer pourquoi vous pensez avoir besoin de deux conteneurs. Expliquez ce que vous essayez d'accomplir. Cela nous aide à comprendre le contexte et, espérons-le, vous aidera davantage. – Steven

+0

Merci Steven, j'ai ajouté un exemple. – Lawrence

+0

quel conteneur utilisez-vous? –

Répondre

1

Ceci n'est pas le cas pour plusieurs conteneurs. Utilisez la configuration du conteneur pour câbler les choses. Si vous avez un grand nombre de composants enregistrés sous l'interface ILogicProxy, alors oui, vous devrez faire plus de câblage manuel. Mais demandez-vous si ces composants doivent être réellement enregistrés sous la même interface.

A propos de l'exemple de code:

Dans un monde idéal, chacune de ces classes fiables fait un appel statique dans son constructeur, qui à son tour injecte les dépendances pensivement d'un récipient approprié ...

public class MyDependableClass{ 
    protected MyApplicationContext Application {get; set;} 
    protected MyRequestContext Request {get; set;} 
    public MyDependableClass() { 
    Dependencies.Inject(this); 
    } 
} 

Il s'agit d'un emplacement de service, pas d'injection de dépendance. Toujours préférer l'injection de dépendance à l'emplacement de service. Essayez de ne pas dépendre des méthodes Resolve() ou Inject() dans vos composants.

+0

Merci Mauricio. Je me souviens vaguement de l'emplacement du service de mes jours de Java à Uni, et oui je suis d'accord, mon échantillon a plus de ressemblance avec cette méthode. Cependant, les fichiers de configuration sont statiques, ce qui signifie que je ne peux pas créer les associations dependency-> reliable au niveau de l'instance, car je ne peux que rendre l'association au niveau de la définition. Par exemple. Je veux 'InstanceA dépend de InstanceB', pas 'ClassA dépend de ClassB'. – Lawrence

+0

@Lawrence: pouvez-vous élaborer sur "les fichiers de configuration sont statiques"? peut-être poster du code? –

0

Il me semble que vous n'avez pas besoin de plusieurs conteneurs, mais que vous devez créer une implémentation de ILogicProxy qui sait comment router.Vous pourriez peut-être mettre en œuvre ce type comme une enveloppe autour d'autres ILogicProxy mise en œuvre, comme ceci:

public class LogicProxyRouter : ILogicProxy 
{ 
    private readonly ILogicProxy local; 
    private readonly ILogicProxy remote; 

    public LogicProxyRouter(ILogicProxy local, ILogicProxy remote) 
    { 
     this.local = local; 
     this.remote = remote; 
    } 

    public void Method(params) 
    { 
     if (someCondition) 
     { 
      this.local.Method(params); 
     } 
     else 
     { 
      this.remote.Method(params); 
     } 
    } 
} 

De cette façon, vous pouvez brancher une seule instance comme ceci:

ILogicProxy proxy = 
    new LogicProxyRouter(new LocalLogicProxy(), new RemoteLogicProxy()); 

// Register that instance in your favorite IoC framework 
container.RegisterSingle<ILogicProxy>(proxy); 

J'espère que cela aide.