Pergunta

Eu estou tentando descobrir o atributo injeção de construtor do MEF. Eu não tenho nenhuma idéia de como eu dizer-lhe para carregar os parâmetros do construtor.

Esta é a propriedade que estou tentando carga

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

Aqui está o código que estou usando para importar os conjuntos.

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);
}

Aqui é a classe Eu estou tentando carga

[Serializable]
[Export(typeof(BUsers))]
public class EditProfile : BUsers
{
    [ImportingConstructor]
    public EditProfile(string Method, string Version)
    {            
        Version = "2";
        Action = "Edit";
        TypeName = "EditProfile";
    }
Foi útil?

Solução

Quando você usa o atributo ImportingConstructor, os parâmetros para o construtor se tornar importações. Por padrão, o que você está importando (o nome do contrato) é baseado no tipo de parâmetro ou propriedade que você está importando para. Portanto, neste caso o tipo de contrato para ambas as suas importações é corda, e não há nenhuma diferença real entre o primeiro eo segundo parâmetro.

Parece que você está tentando usar importações para fornecer valores de configuração, o que não é necessariamente o que ele foi projetado para. Para obtê-lo para fazer o que você quer, você deve substituir o nome do contrato para cada um dos parâmetros, como este:

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

Então você precisa exportações para o Método e Versão em seu recipiente. Uma maneira de fazer isso é só adicioná-los diretamente:

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

(Note que ComposeExportedValue é realmente um método de extensão definido na classe AttributedModelServices estáticos.)

Se você quiser ler esses valores de um arquivo de configuração de algum tipo, você pode criar seu próprio provedor de exportação, que lê a configuração e fornece os valores em que as exportações para o recipiente.

Uma forma alternativa de lidar com isso seria apenas para importar uma interface que dá acesso aos valores de configuração pelo nome, e obter os valores que você precisa a partir do corpo do construtor.

Outras dicas

Eu como solução de Daniel; no entanto, apenas uma coisa que eu vejo é o acoplamento forte de nomes de parâmetros entre o ator (que cria CompopositionContrainer ()) e parte de exportação com [ImportingConstructor] para CTOR personalizado. Por exemplo, "Método" tem dois ser combinados em ambos os lugares. Faz difícil de manter a parte de exportação se o ator e Exportação parte estão em projetos de diferença.

Se for possível, gostaria de acrescentar o segundo CTOR à classe parte Export. Por exemplo:

[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";
    }

A classe de EditProfileParameters deve ser simples: duas propriedades do Método e Versão:

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

O ponto-chave é adicionar o atributo de exportação para a classe. Então MEF deve ser capaz de mapear essa classe para o parâmetro de CTOR de EditProfile.

Aqui está um exemplo para adicionar a parte de exportação para o recipiente:

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

Embora tarde para o jogo, aqui está uma outra abordagem que aproveita um recurso menos conhecido da MEF: Exportações de Propriedade

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

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

Não há usos são necessários para ObjectMother para este ao trabalho, e sem atributos são necessários em EditProfile.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top