9
votes

Injection de dépendance avec interface mise en œuvre par plusieurs classes

Mise à jour: strong> Y a-t-il un moyen de réaliser ce que j'essaie de faire dans un cadre IOC autre que Windsor? Windsor gérera bien les contrôleurs, mais ne résout rien d'autre. Je suis sûr que c'est de ma faute, mais je suis sur le tutoriel Verbatim et que les objets ne résolvent pas avec une injection cors, ils sont toujours nuls malgré les registres et résoudre. Depuis, j'ai mis au rebut mon code di et j'ai une injection manuelle pour le moment, car le projet est sensible au temps. Dans l'espoir d'obtenir di orthé avant la date limite.


J'ai une solution qui a plusieurs classes qui mettent tous la même interface p>

comme exemple simple, l'interface code> P> xxx pré>

Les classes de béton p> xxx pré>

Ces classes seront injectées si nécessaire dans les couches au-dessus d'eux comme: p > xxx pré>

Les deux contrôleurs sont injectés avec la même interface. P>

En ce qui concerne la résolution de ces interfaces avec la classe de béton appropriée de mon CIO, comment différencier cela HOMECONTROLLER CODE> a besoin d'une instance de MyClassone CODE> et AutresController CODE> Besoin d'une instance de MyClasSTWO ​​code>? P>

Comment Est-ce que je lie deux classes de béton différentes à la même interface dans le CIO? Je ne veux pas créer 2 interfaces différentes car cela brise la règle sèche et n'a aucun sens de toute façon. P>

dans le château Windsor, j'aurais 2 lignes comme ceci: p>

public class Dependency : IDependency {

    private readonly WindsorContainer container = new WindsorContainer();

    private IDependency() {
    }

    public IDependency AddWeb() {
        ...

        container.Register(Component.For<IListItemRepository>().ImplementedBy<ProgramTypeRepository>().Named("ProgramTypeList"));
        container.Register(Component.For<IListItemRepository>().ImplementedBy<IndexTypeRepository>().Named("IndexTypeList"));

        return this;
    }

    public static IDependency Start() {
        return new IDependency();
    }
}


5 commentaires

Vous pouvez lier directement sur les classes de béton si nécessaire. (Eh bien, du moins avec Niject tu peux mais je ne peux pas imaginer que tu ne peux pas le faire avec d'autres trempettes.)


Vous ne voulez pas faire ça. Les dépendances de vos classes sont ambiguës. Vous ne pouvez pas simplement regarder l'une des classes et dire qu'il a besoin d'une implémentation spécifique. Je vous recommande d'utiliser une usine comme une dépendance dans les deux classes. En savoir plus ici: CodeProject.com/ Articles / 386164 / ...


@JGAUFFIN La promesse de de Windsor (...) est qu'il peut résoudre cette ambiguïté, mais en utilisation réelle, je ne peux pas obtenir Windsor de résoudre quoi que ce soit :-(


Tu ne me m'aies pas. Vous ne pouvez pas dire en examinant le constructeur de classe qu'une implémentation spécifique est requise. C'est une sorte de violation de principe de substitution de Liskovs.


@jgauffin Je comprends ça complètement. C'est toute l'idée de OOP, pouvant accepter une base et fournir une mise en œuvre plus spécifique. Mais dans les deux sens, comme je l'ai dit, je ne peux pas avoir à Windsor de résoudre quoi que ce soit, pas seulement ces classes qui ont une ambiguïté.


3 Réponses :



5
votes

Vous devriez être capable de l'accomplir avec l'enregistrement de composant nommé.

kernel.Resolve<IMyInterface>("Two");


5 commentaires

Je travaille en désactivée d'une exemple d'application qui utilise le château Windsor, il utilise le conteneur.register (... lignes mais il n'utilise aucun conteneur.Resolve ... Anywhere. Existe-t-il un endroit spécifique que conteneur.Resolve ... va ou juste là après .register ?


Désolé, au lieu de conteneur, il devrait être du noyau, où le noyau est de type noyau.


J'ai mis à jour ma question avec mon CIO actuel, c'est dans une assemblée séparée de mon UI MVC et il n'a actuellement pas de Kernel objet .. Où va-t-il?


Vous devriez pouvoir appeler la résolution de votre instance de conteneur. Cela ne doit pas nécessairement venir de l'instance du microkernel.


Cette méthode ne fonctionne pas :-( Windsor ne résout aucune des dépendances pour une raison quelconque. J'ai suivi le tutoriel sur le château wiki. Le contrôleursInstaller fonctionne mais le reste omet de résoudre



2
votes

Les conteneurs typiquement di suivent le registre, la résolution et la libération des modèles. Pendant la phase de registre, il y a deux étapes. Le premier est de spécifier la cartographie comme vous le faites. La deuxième étape consiste à spécifier les règles qui régissent lesquelles l'injection d'injection.

Ce problème est très courant lorsque nous essayons d'aborder des préoccupations transversales à l'aide de décorateurs. Dans ces situations, vous avez plusieurs classes (décorateurs) implémentant une seule interface.

Brièvement, nous devons mettre en œuvre imodelinterceptorselector qui vous permet d'écrire un code impératif qui décide de l'intercepteur à appliquer à quels types ou membres.

Ceci est décrit minutieusement dans l'injection de dépendance du livre dans le livre .NET par Mark Semelann. Recherchez le chapitre 9 Interception ou recherchez l'interface ci-dessus.

Je ne suis pas un expert à cela, mais cherchait exactement le même problème et trouvé les ANS dans le livre ci-dessus.

J'espère que cela aide.

Cordialement Dev1


0 commentaires