2010-05-30 10 views
2

Je travaille sur un programme qui communiquera avec différents matériels. En raison de la nature variée des éléments qu'il communique et contrôle, j'ai besoin d'un "pilote" différent pour chaque composant matériel. Cela m'a fait penser que MEF serait un excellent moyen de faire de ces pilotes des plugins qui peuvent être ajoutés même après la sortie du produit. J'ai examiné de nombreux exemples d'utilisation de MEF, mais la question à laquelle je n'ai pas trouvé de réponse est comment remplir un plugin MEF avec des données externes (par exemple, à partir d'une base de données)). Tous les exemples que je peux trouver pour avoir les « données » codées en dur dans l'ensemble, comme l'exemple suivant:Comment remplir un plugin MEF avec des données qui ne sont pas codées en dur dans l'assembly?

[Export(typeof(IRule))] 
public class RuleInstance : IRule 
{ 
    public void DoIt() {} 

    public string Name 
    { 
     get { return "Rule Instance 3"; } 
    } 

    public string Version 
    { 
     get { return "1.1.0.0"; } 
    } 

    public string Description 
    { 
     get { return "Some Rule Instance"; } 
    } 
} 

Et si je veux nom, la version et la description proviennent d'une base de données? Comment dirais-je au MEF où trouver cette information?

Je peux manquer quelque chose de très évident, mais je ne sais pas ce que c'est.

Répondre

3

Vous devez soit transmettre les informations au plug-in après chargé via les propriétés:

[Export(typeof(IRule))] 
public class RuleInstance : IRule 
{ 
    puliic void DoIt() 
    { } 

    public string Name { get; set; } 
} 

public class Program 
{ 
    [Import(typeof(IRule))] 
    public IRule instance { get; set; } 

    public void Run() 
    { 
     // Load the assemblies here 

     instance.Name = "Rule Instance 3"; 
    }    
} 

Ou le plugin pourrait demander les variables via une interface hôte. Vous pouvez soit passer l'instance IHost via une propriété, soit via un paramètre constructeur, mais les paramètres du constructeur ne sont pas simples avec MEF. Voici par une propriété:

[Export(typeof(IRule))] 
public class RuleInstance : IRule 
{ 
    puliic void DoIt() 
    { } 

    public void Initialise() 
    { 
     // Load our name from the host, this cannot be done in the constructor 
     string name = Host.GetName(/* some parameters? */) 
    } 


    public IHost Host { get; set; } 
    public string Name { get; set; } 
} 

public interface IHost 
{ 
    string GetName(/* some parameters? */); 
} 

public class Program : IHost 
{ 
    [Import(typeof(IRule))] 
    public IRule instance { get; set; } 

    public void Run() 
    { 
     // Load the assemblies here  

     // Make sure the plugins know where the host is... 
     instance.Host = this; 
    }    
} 

Vous pouvez également « Exporter » l'interface de base de données et « Importer » dans tous les plug-ins qui ont besoin d'un accès de base de données ...

+0

Oui, ceux-ci ont un sens. Cela semble plutôt simple. Dans votre exemple d'hôte, vous avez utilisé une fonction "Initialize()". MEF appelle-t-il toujours cette fonction si elle existe dans la partie composable exportatrice? – hjoelr

+1

@hjoelr Non, MEF n'appelle pas automatiquement cette fonction. Vous devriez l'appeler de l'hôte. Vous pouvez également exporter l'hôte, l'importer à partir des plugins, puis implémenter l'interface IPartImportsSatisfiedNotification sur vos plugins et leur demander d'initialiser la méthode OnImportsSatisfied. –

1

Vous pouvez toujours exporter des valeurs individuelles (par contrat noms), voici un exemple:

public class Configuration 
{ 
    [Export("SomeValue")] 
    public string SomeValue 
    { 
    get { /* return value from database perhaps? */ } 
    } 
} 

[Export(typeof(IRule))] 
public class RuleInstance : IRule 
{ 
    [Import("SomeValue")] 
    public string SomeValue { get; private set; } 
}