Самый простой способ - создать существующее значение в контейнере, например:
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.