Инжекция конструктора MEF

Я пытаюсь выяснить атрибут Инжекции Конструктора MEF. Я понятия не имею, как я говорю этому загружать параметры конструктора.

Это - свойство, которое я пытаюсь загрузить

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

Вот код, который я использую для импорта блоков.

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

Вот класс, который я пытаюсь загрузить

[Serializable]
[Export(typeof(BUsers))]
public class EditProfile : BUsers
{
    [ImportingConstructor]
    public EditProfile(string Method, string Version)
    {            
        Version = "2";
        Action = "Edit";
        TypeName = "EditProfile";
    }
39
задан valdetero 30 September 2016 в 19:38
поделиться

2 ответа

При использовании атрибута ImportingConstructor параметры конструктора становятся импортируемыми. По умолчанию, то, что вы импортируете (имя контракта), основано на типе параметра или свойства, в которое вы импортируете. Так что в этом случае тип контракта для обоих ваших импортов является строчным, и нет никакой реальной разницы между первым и вторым параметром.

Похоже, что вы пытаетесь использовать импорт для поставки значений конфигурации, что не обязательно является тем, для чего он был разработан. Чтобы заставить его делать то, что вы хотите, вы должны переопределить имя контракта для каждого из параметров, например:

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

Затем вам нужен экспорт для Method и Version в вашем контейнере. Один из способов сделать это - просто добавить их напрямую:

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

(Обратите внимание, что ComposExportedValue на самом деле является методом расширения, определенным на статическом классе AttributedModelServices)

Если вы хотите прочитать эти значения из какого-нибудь конфигурационного файла, вы можете создать свой собственный провайдер экспорта, который будет читать конфигурацию и предоставлять значения в ней в виде экспортированных данных в контейнер.

Альтернативным способом решения этой проблемы был бы просто импорт интерфейса, предоставляющего доступ к значениям конфигурации по имени, и получение нужных значений из тела конструктора.

55
ответ дан 27 November 2019 в 02:28
поделиться

Мне нравится решение Даниила; Тем не менее, только одно, что я вижу, - это тесная связь имен параметров между актером (который создает компосотконтрайн ()) и экспортную часть с [ImportingConstructor] для индивидуального CTOR. Например, «метод» имеет два в обоих местах. Трудно поддерживать экспортную роль, если актер и экспортная часть находятся в разностных проектах.

Если это возможно, я бы добавил второй CTOR в класс экспорта деталей. Например:

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

Класс EditProfileParameters должен быть простым: два свойства метода и версии:

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

Основная точка - добавить атрибут экспорта в класс. Тогда MEF должен иметь возможность сопоставить этот класс к параметру CTOR EditProfile.

Вот пример добавления экспорта части к контейнеру:

var container = new CompositionContainer(catalog);
var instance1 = new EditProfileParameters();
// set property values from config or other resources
container.ComposeExportedValue(instance1);
container.ComposeParts(this);
24
ответ дан 27 November 2019 в 02:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: