2010-06-10 11 views
2

Y a-t-il moyen d'utiliser IoC, MEF [Imports] ou une autre solution DI pour composer des dépendances à la volée au moment de la création de l'objet plutôt qu'au moment de la composition?IoC - Composition dynamique des instances d'objets

Voici ma pensée actuelle. Si vous avez une instance d'un objet qui déclenche des événements, mais que vous ne créez pas l'objet une seule fois et que vous ne l'enregistrez pas en mémoire, vous devez enregistrer les gestionnaires d'événements chaque fois que l'objet est créé. Autant que je sache, la plupart des conteneurs de l'IoC exigent que vous enregistriez toutes les classes utilisées dans la composition et appelez Compose() pour que toutes les dépendances soient connectées.

Je pense que cela peut être horrible design (j'ai affaire à un système hérité ici) pour ce faire en raison de la surcharge de création d'objet, injection de dépendance, etc ... mais je me demandais si c'était possible des technologies émergentes de l'IoC. Peut-être que j'ai une terminologie mélangée, mais mon but est d'éviter d'écrire un framework pour "connecter tous les événements" sur une instance d'un objet, et utiliser quelque chose comme MEF pour gérer les [gestionnaires] (dépendances) adhérer à une interface très spécifique et [les importer] dans une instance d'objet afin que mes exportations soient appelées si les assemblages sont là quand l'application démarre. Alors peut-être que tous les objets peuvent encore être composés quand l'application démarre, mais je veux que le système les trouve et les appelle tous quand l'objet est créé et détruit.

Répondre

4

Généralement, la façon dont vous gérez l'instanciation à la volée dans un environnement DI/IoC consiste à utiliser des usines abstraites. L'usine est le seul type de classe autorisé à interagir directement avec le conteneur, afin de résoudre les dépendances lors de l'instanciation d'un nouvel objet.

public interface IWidgetFactory 
{ 
    IWidget CreateWidget(...); 
} 

public class MyIocWidgetFactory : IWidgetFactory 
{ 
    private IoCContainer container; 

    public MyIocWidgetFactory(IoCContainer container) 
    { 
     if (container == null) 
      throw new ArgumentNullException("container"); 
     this.container = container; 
    } 

    public IWidget CreateWidget(...) 
    { 
     // Assumes that the container is configured to create transient objects 
     // for IWidget, not a singleton. 
     return container.Resolve<IWidget>(); 
    } 
} 

Veuillez ne pas confondre avec le localisateur de service anti-pattern; rien d'autre n'est autorisé à toucher le conteneur, juste l'usine, et cela crée seulement un type d'objet.

À ce stade, vous passez simplement le IWidgetFactory à tout ce dont vous avez besoin pour créer un widget lors de l'exécution. C'est tout - vous avez maintenu DI.

+0

Certains conteneurs DI prennent également en charge la génération d'usines pour vous. Vous pouvez injecter par exemple un Func -delegate. Le conteneur DI génère ensuite une fabrique pour les instances IWidget. Par exemple dans Autofac: http://nblumhardt.com/2010/01/the-relationship-zoo/ – Gamlor

+0

Je suis curieux, auriez-vous besoin d'injecter cette usine dans la classe qui voulait créer l'objet dans le premier endroit? Ou cela aurait-il besoin d'être instancié? – stuartmclark

+1

@stuartmclark: Vous injectez l'usine. C'est pourquoi c'est un 'IWidgetFactory' et pas un type concret. Plusieurs conteneurs IoC sont en fait capables de générer automatiquement les usines, donc vous n'avez même pas besoin des types ci-dessus, vous pouvez simplement injecter un 'Func ' ou 'Lazy '. – Aaronaught