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.
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
@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
@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. –