2013-11-13 3 views
0

В моем интерфейсе пакета у меня есть этот следующий кусок кода, который выполняется, когда пользователь хочет изменить некоторую информацию о художнике:IoC/MEF контейнер

IArtist artistToChange = ContainerHelper.Container.GetExportedValue<IArtist>(); 
artistToChange.Load(new Guid("provided guid")); 
artistToChange.SomeProperty = newValue; 
artistToChange.Update(); 

Being художнику объект в моей области состоит из другие вещи от IUser CreatedBy & IUser LastAlteredBy свойства, которые необходимо загрузить (подумайте о взаимоотношениях «много-к-одному»). У каждого объекта также есть собственный репозиторий. IArtist имеет IArtistRepository так же, как IUser имеет IUserRepository.

Моя проблема заключается в следующем: Как я могу получить экземпляр конкретной реализации IUser внутри IArtist.Load() при сохранении IoC (без конкретной реализации IArtist не зная о конкретной реализации IUser)?

(Для того, чтобы сделать вызов вещи легко ДАВАЙТЕ из CArtist конкретной реализации IArtist и CUser об осуществлении IUser.)

Имея это в виду я, хотя о прохождении контейнера к лиц, чтобы они могли также запрашивать детали, но я не знаю, является ли это хорошей идеей или даже анти-шаблоном, главным образом потому, что им используется инсталляция конструктора, а мой конструктор для «CArtist» выглядит так:

[ImportingConstructor] 
public CArtist(IArtistRepository repository) 
{ 
    this.repository = repository; 
} 

, но я не могу получить контейнер, чтобы придать себя с чем-то вроде

[ImportingConstructor] 
public CArtist(IArtistRepository repository, CompositionContainer container) 
{ 
    this.container = container  
    this.repository = repository; 
} 

Так что это в основном это ... Я совершенно потерял здесь ... это оказался крик о помощи/руководство более чем вопрос о себе ...

PS: Если какая-либо другая информация необходима, попросите ее!

+0

Как вы собираетесь использовать контейнер в классе CArtist? Будет ли контейнер более гибким, чем свойства, украшенные ImportAttribute? –

ответ

1

Если вы правильно экспортировать конкретный IArtist класс, вы можете сделать следующее в вашем коде, а затем до тех пор, как DLL файлы доступны, когда вы сочинить CArtist класс, то IArtist тип бы получить вводили в класс. Вы можете быть в состоянии даже уйти с частной переменной private IArtist _someArtist; (помеченных атрибутом импорта)

public class CArtist : IArtist 
{ 
    [ImportingConstructor] 
    public CArtist(IArtistRepository repository) 
    { 
     this.repository = repository; 
    } 

    public void Load(Guid guid) 
    { 
     this.SomeArtist.DoSomething(guid); 
     ... 
    } 

    [Import(typeof(IArtist))] 
    private IArtist SomeArtist { get; set; } 
} 

Другой подход, должен был бы снова использовать свойство или вар в классе, и импортировать его в конструкторе

private IArtist _artist; 

[ImportingConstructor] 
public CArtist(IArtistRepository repository, IArtist artist) 
{ 
    this.repository = repository; 
    this._artist = artist; 
} 

Помимо этих возможных подходов, имхо прохождение контейнера не будет слишком большой проблемой, она будет работать, и вы по-прежнему поддерживать разделение, я видел, что сделано в нескольких местах, но я «Я не знаю экспертов в IoC, чтобы точно знать, является ли это хорошей или плохой практикой.

+0

интересный ... пока я разместил контейнер в Библиотеке (проект имеет только интерфейсы и счетчики), потому что все проекты ссылаются на него ... Я создал вспомогательный класс, который вернул бы контейнер в качестве одноэлементного ... я думаю это хороший подход ... как вы думаете? – Leonardo

+0

@ Leonardo это сработало бы, как говорится, * есть более чем один способ обмануть кошку * (обратите внимание всем, в этом идиоматическом выражении на самом деле не пострадало ни одна кошка). Хотя я лично не принимал такой подход, imho клиент (ы) должен позаботиться о том, чтобы составлять все, что необходимо, а не в общую библиотеку, где интерфейсы и перечисления: – Jason

Смежные вопросы