2011-09-01 2 views
2

Pour cet exemple, vous pouvez supposer que toplevel est en train d'importer ClassA. MEF semble fonctionner aussi bien que vous importez tout (ie ClassX). Souvent, vous n'avez pas besoin d'importer car classB est dans le même espace de noms/fichier. Par conséquent, la chaîne d'importation est maintenant interrompue et l'importation myLog n'est jamais composée. Dans mon exemple, ClassB tente d'importer un service de journalisation, ce que presque toutes les classes pourraient souhaiter.Rupture de la chaîne d'importation .NET MEF

Lequel, le cas échéant, est la meilleure solution MEF pour ce problème?

1) Une fois la chaîne d'importation rompue, n'utilisez plus jamais l'importation. Au lieu de cela, vous devez commencer à créer/passer tous les types au constructeur (c'est-à-dire nouveau ClassB (myLog)). Cela fonctionne dans cet exemple mais il est désordonné s'il y a des classes intermédiaires dans la chaîne n'utilisant pas l'argument.

2) Utilisez IServiceLocator dans l'espace de noms System pour importer ClassB. Autant que je sache, ServiceLocator (par exemple, Prism Framework) n'existe que pour résumer le schéma d'injection de dépendances. Pour cet exemple, si ClassB pouvait importer l'IServiceLocator, il aurait pu importer ILogger.

3) De retour au niveau supérieur, appelez ComposeParts (ClassB). Pour empêcher le toplevel de dépendre de ClassB, je pourrais avoir classB implémenter une interface (IComposeMe), que le toplevel importe. Ensuite, le niveau supérieur composerait ComposeParts sur le conteneur pour toutes les importations IComposeMe. Je ne crois pas que ce soit la solution prévue, car elle n'est pas décrite ou utilisée dans la documentation du cadre MEF.

4) En fait, je suis d'idées, s'il vous plaît aider ...

class ClassA { 

    // Imports within ClassX will get composed 
    [Import] 
    ClassX myClassX; 

    // Imports within ClassB will NOT be composed! 
    var myClassB = new ClassB 
} 

class ClassB { 

    // Fails because ClassB is never Composed 
    [Import] 
    ILogger myLog; 

    myLog.Display("Hello World"); 
} 

[Export] 
class ClassX { 

    // Works - Imports are satified when ClassX imported 
    [Import] 
    ILogger myLog; 

    myLog.Display("Hello World"); 
} 

Répondre

0

Certes, vous pouvez vous inscrire quelque part quels types vous voulez avoir importé/exporté sans avoir à analyser l'ensemble. Je ne sais pas si cela vous aidera, mais voici un lien que j'ai trouvé après googler un peu: http://blogs.microsoft.co.il/blogs/zuker/archive/2010/10/17/mef-runtime-type-catalog-support-multi-registrations-in-runtime.aspx

+0

Votre réponse est utile mais pas liée à ma question. Votre sujet/lien considère la réduction du nombre de pièces dans un conteneur en enregistrant des types. J'ai modifié ma question et mon code pour mieux illustrer mon problème. Je dois satisfaire les importations dans une classe qui n'a pas d'attribut d'exportation (ne fait pas partie de la chaîne d'importation). – aidesigner

1

L'approche préférée si vous suivez le schéma d'injection de dépendance? Ne pas casser la chaîne d'importation. Vous devriez avoir une seule racine de composition dans votre application où les composants sont câblés ensemble. Les composants eux-mêmes ne devraient pas être concernés par l'acquisition de leurs dépendances. Certes, en pratique, vous devez faire face à du code existant (et à d'autres développeurs sceptiques de DI), donc vous ne pouvez pas toujours faire de l'injection de dépendance "tout le long". Dans ces cas, vous pouvez exposer le conteneur en tant que variable globale et extraire les dépendances nécessaires à partir de là.

L'exposition du conteneur comme global est essentiellement le modèle Service Locator. Il a cependant disadvantages.

Questions connexes