Можно ли внедрить существующий экземпляр в плагин MEF? - PullRequest
4 голосов
/ 07 октября 2011

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

Например, мы создаем плагин, который может отображать список. Для этого ему необходим существующий экземпляр IRepository для типа данных, отображаемых в списке.

IRepository создается где-то еще в классе datacontext, поэтому мы не можем позволить самому MEF создать экземпляр IRepository.

Моя идея состоит в том, чтобы внедрить существующий экземпляр IRepository в плагин через конструктор importing, однако, чтобы это работало, мне нужно, чтобы уже созданный экземпляр IRepository был известен MEF, и я не смог выяснить, как сделай это. Любая помощь будет оценена.

1 Ответ

8 голосов
/ 07 октября 2011

Самый простой способ - создать существующее значение в контейнере, например:

var repo = // Create repo
container.ComposeExportedValue<IRepository>(repo);

Но это позволит только одному экземпляру IRepository существовать, посколькуне дает вам прямого контроля над ComposablePart, который создается.Если вам нужен более точный контроль, вы можете использовать CompositionBatch с большим эффектом:

var batch = new CompositionBatch();
var repo = // Create repo

var repoPart = batch.AddExportedValue<IRepository>(repo);
container.Compose(batch);

// repo will now be injected on any matching [Import] or [ImportingConstructor]

И позже:

var batch2 = new CompositionBatch(null, new[] { repoPart });
var repo2 = // Get new repo

var repo2Part = batch2.AddExportedValue<IRepository>(repo2);
container.Compose(batch2);

Поскольку у меня есть доступ к ComposablePartэкземпляр, предоставленный пакетом, я могу удалить его позже.Существуют и другие способы импорта деталей без атрибутов, обычно с помощью экспорта свойств:

[Export(typeof(IRepository))]
public IRepository Repository
{
    get { return CreateRepository(); }
}

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

Наконец, есть возможность использовать альтернативную модель программирования.По умолчанию (и наиболее распространенным) в MEF является атрибутивная модель с атрибутом , в которой вы используете атрибуты [Export] и [Import] для управления композицией, но в MEFContrib (и готовится к выпуску в MEF2) есть возможностьиспользуйте регистрационную модель программирования, в которой детали составляются на основе механизма, аналогичного большинству других контейнеров IoC.

...