Контроль того, какая часть составлена ​​в MEF - PullRequest
0 голосов
/ 07 декабря 2011

У меня есть следующие классы:

public class Foo
{
    [Import]
    public IFirstInterface firstImport;

    [Import]
    public ISecondInterface secondImport;

    // ...
}

public class A : ISecondInterface {}

public class B : ISecondInterface {}

Я хотел бы иметь возможность в классе Bar, при вызове

var foo = compositionContainer.GetExportedValue<Foo>();

Чтобы указать, хочу ли я использовать класс A или B.

Я знаю, я могу указать имя контракта в методе GetExportedvalue.Но насколько я понимаю, это будет означать наличие двух классов Foo.Я хотел бы повторно использовать тот же класс, но указать, какой класс (A или B) используется для удовлетворения зависимости ISecondInterface.

EDIT:"Какие правила будут определять, используете ли выкласс A или B? "

A: Foo вызывается службой wcf.Класс A и B отличаются тем, что они работают на разных объектах.Эти объекты имеют разные поля и не могут быть запрошены одинаково.

Мои занятия не на английском языке, но я постараюсь перевести на более значимые термины, чем Foo и Bar.

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

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

На уровне обслуживания я хочу иметь возможность вызывать методы с именами AssignRecordTypeA и AssignRecordTypeB безДублирование всего кода в RecordAssigner.

Ответы [ 2 ]

1 голос
/ 08 декабря 2011

Я не могу сразу придумать способ сделать это в MEF, не создавая никаких дополнительных классов.Лучшее, что я могу придумать, это создать подклассы Foo с различными [Import] спецификациями.

Другие контейнеры, такие как AutoFac (см. пример ) или Ninject (см. контекстная привязка ) может дать вам более детальный контроль.

1 голос
/ 07 декабря 2011

Какие правила будут определять, используете ли вы класс A или B? Вы можете написать свой собственный распознаватель для экспорта MEF.

В этом сообщении в блоге http://randomactsofcoding.blogspot.com/2010/01/configurable-type-catalog-for-mef.html упоминается один подход, и есть несколько других, которые вы можете найти, если вы ищете "mef custom export provider" или "mef custom catalog"

EDIT: Ваш сценарий немного напоминает мне разговор с некоторыми коллегами некоторое время назад. На мой взгляд, MEF предназначен для «расширений» вашего приложения, а не для зависимостей. Случай, который у вас есть, больше похож на зависимости. Так что вам лучше использовать контейнер IoC для управления вашими зависимостями. Можно использовать несколько экземпляров ISecondInterface с разными ключами, а затем выбирать, какой из них использовать.

Если вы чувствуете, что MEF более соответствует вашим требованиям, вы все равно можете сделать это, изменив

public class Foo
{
    [Import]
    public IFirstInterface firstImport;

    [ImportMany]
    public Collection<ISecondInterface> secondImport;

    // ...
}

и затем решить, какой из них использовать.

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

...