Question

Je suis en train de comprendre Constructor attribut d'injection de MEF. Je ne sais pas comment je le dis pour charger les paramètres du constructeur.

est la propriété que je suis en train de charger

[ImportMany(typeof(BUsers))]
public IEnumerable<BUsers> LoadBUsers { get; set; }

Voici le code que je utilise pour importer les assemblages.

try
{
    var catalog = new AggregateCatalog();
    catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
    catalog.Catalogs.Add(new DirectoryCatalog("DI")); 
    var container = new CompositionContainer(catalog);
    container.ComposeParts(this);
}

Voici la classe que je suis en train de charger

[Serializable]
[Export(typeof(BUsers))]
public class EditProfile : BUsers
{
    [ImportingConstructor]
    public EditProfile(string Method, string Version)
    {            
        Version = "2";
        Action = "Edit";
        TypeName = "EditProfile";
    }
Était-ce utile?

La solution

Lorsque vous utilisez l'attribut ImportingConstructor, les paramètres au constructeur deviennent les importations. Par défaut, ce que vous importez (le nom du contrat) est basé sur le type de paramètre ou bien que votre importent en. Donc, dans ce cas, le type de contrat pour les deux vos importations est une chaîne, et il n'y a pas de différence réelle entre le premier et le second paramètre.

Il semble que vous essayez d'utiliser les importations pour fournir des valeurs de configuration, ce qui est pas nécessairement ce qu'il a été conçu. Pour obtenir de faire ce que vous voulez, vous devez remplacer le nom de contrat pour chacun des paramètres, comme ceci:

[ImportingConstructor]
public EditProfile([Import("Method")] string Method, [Import("Version")] string Version)
{ }

Ensuite, vous devez l'exportation pour la méthode et la version dans votre récipient. Une façon de le faire est juste pour les ajouter directement:

var container = new CompositionContainer(catalog);
container.ComposeExportedValue("Method", "MethodValue");
container.ComposeExportedValue("Version", "2.0");
container.ComposeParts(this);

(Notez que ComposeExportedValue est en fait une méthode d'extension définie dans la classe AttributedModelServices statique.)

Si vous voulez lire ces valeurs à partir d'un fichier de configuration de quelque sorte, vous pouvez créer votre propre fournisseur d'exportation qui lit la configuration et fournit les valeurs comme les exportations vers le conteneur.

Une autre façon de gérer cela serait d'importer simplement une interface qui permet d'accéder aux valeurs de configuration par nom, et obtenir les valeurs dont vous avez besoin du corps du constructeur.

Autres conseils

J'aime la solution de Daniel; Cependant, une seule chose que je vois est le couplage étroit des noms de paramètres entre l'acteur (qui crée CompopositionContrainer ()) et une partie à l'exportation avec [ImportingConstructor] pour CTOR personnalisé. Par exemple, « Méthode » a deux être adapté dans les deux endroits. Il est difficile de maintenir la partie à l'exportation si l'acteur et une partie des exportations sont des projets de différence.

S'il est possible, je voudrais ajouter la deuxième CTOR à la classe Export partiel. Par exemple:

[Export(typeof(BUsers))] 
public class EditProfile : BUsers
{
    [ImportingConstructor]
    public EditProfile(EditProfileParameters ctorPars)
    : this(ctorPars.Method, ctorPars.Version) {}

    public EditProfile(string Method, string Version)
    {
        Version = "2";
        Action = "Edit";
        TypeName = "EditProfile";
    }

La classe de EditProfileParameters devrait être simple: deux propriétés de la méthode et Version:

[Export]
public class EditProfileParameters{
   public string Method { get; set; }
   public string Version { get; set; }
}

Le point clé est d'ajouter l'attribut d'exportation à la classe. Alors MEF devrait pouvoir cartographier cette classe au paramètre de CTOR de EditProfile.

Voici par exemple d'ajouter la partie Exporter vers conteneur:

var container = new CompositionContainer(catalog);
var instance1 = new EditProfileParameters();
// set property values from config or other resources
container.ComposeExportedValue(instance1);
container.ComposeParts(this);

Bien que la fin du jeu, voici une autre approche qui tire parti d'une caractéristique de MEF moins connu: Exportations de propriété

public class ObjectMother
{
    [Export]
    public static EditProfile DefaultEditProfile
    {
        get
        {
            var method = ConfigurationManager.AppSettings["method"];
            var version = ConfigurationManager.AppSettings["version"];

            return new EditProfile(method,version);
        }
    }
}

Aucun usages sont nécessaires pour ObjectMother pour que cela fonctionne, et pas d'attributs sont nécessaires sur EditProfile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top