2010-12-09 60 views
4

Comme je sais si une variable est déclarée Lazy, alors son constructeur est appelé lorsque nous utilisons la propriété Value.Passer les paramètres au constructeur, lors de l'initialisation d'une instance paresseuse

Je dois passer certains paramètres à cette instance Lazy mais je ne trouve pas la syntaxe correcte. Ce n'est pas ma conception, j'utilise MEF et ExportFactory, il me renvoie Lazy instances de mes parties. Mes parties ont des constructeurs et j'ai besoin d'appeler ces constructeurs avec quelques paramètres.

Répondre

2

MEF ne dispose pas d'une méthode intégrée permettant de transmettre des paramètres de constructeur à une pièce lorsque vous le créez avec une exportation. Quelque chose comme ce que suggère Wim Coenen est probablement le meilleur moyen de réaliser ce que vous voulez.

8

Vous pouvez exporter votre propre Func à la place:

public class FooFactory 
{ 
    [Export(typeof(Func<string,int,ExportLifetimeContext<IFoo>>))] 
    public ExportLifetimeContext<IFoo> CreateFoo(string param1, int param2) 
    { 
     Foo foo = new Foo(param1, param2); 
     return new ExportLifetimeContext<IFoo>(foo, 
      delegate 
      { 
       // Clean-up action code goes here. The client might not be able 
       // to do this through the IFoo interface because it might not 
       // even expose a Dispose method. 
       // 
       // If you created other hidden dependencies in order to construct 
       // Foo, you could also clean them up here. 
       foo.Dispose(); 
      }); 
    } 
} 

et l'importer ailleurs:

[Export(typeof(ISomething))] 
public class FooUser : ISomething 
{ 
    private readonly Func<string,int,ExportLifetimeContext<IFoo>> fooFactory; 

    [ImportingConstructor] 
    public FooUser(Func<string,int,ExportLifetimeContext<IFoo>> fooFactory) 
    { 
     this.fooFactory = fooFactory; 
    } 

    public void DoSomething() 
    { 
     using (var fooLifetime = this.fooFactory("hello", 3)) 
     { 
      IFoo foo = fooLifetime.Value; 
      ... 
     } 
    } 
} 

Si vous n'avez pas besoin alors l'action de nettoyage pourrait vous simplifier considérablement en jetant sur tous les trucs ExportLifetimeContext. Cependant, certaines implémentations de IFoo peuvent être jetables (ou dépendent d'autres objets jetables) alors que d'autres ne le sont pas. Donc, la chose la plus correcte à faire est de construire un signal "Je suis fait avec cet objet" dans l'abstraction, qui est ce que ExportLifetimeContext fournit.

+0

Les pièces ne sont pas entièrement fiables dans mon cas. Aussi puisque je n'ai aucune idée (du côté de l'exportateur) qui appelle le Func exporté, j'ai besoin d'un identifiant pour être passé en paramètre de la fonction. De cette façon, la partie réclame qui il est. C'est un trou de sécurité qu'une partie peut prétendre être quelqu'un d'autre et je renverrai des données sensibles d'une autre partie à celle-ci. Ce problème peut être résolu par la conception au moment où je crée l'objet. À ce stade, en utilisant les métadonnées, je sais quelle partie je crée et je peux facilement injecter ses dépendances spécifiques à son constructeur. – Xaqron

+0

@Wim: Je charge des plugins à partir d'un dossier. Votre ligne Foo foo = new Foo (param1, param2) me pose un problème car je ne connais pas "Foo" au moment de l'implémentation. Cela fonctionne bien avec ExportFactory, mais maintenant j'ai besoin de passer un paramètre à un type de ViewModel dans les plugins. Aucune suggestion? – ps23

+0

@PatrickS: Je suppose que vous pouvez scanner vous-même les assemblys pour les types implémentant 'IFoo', et ensuite appeler le constructeur via la réflexion. C'est un peu trop loin de la portée de la question initiale de répondre en détail ici, car je ne pense pas que le MEF serait d'une grande aide pour cela. –