Как освободить общий экземпляр из контейнера MEF - PullRequest
5 голосов
/ 25 марта 2011

Я пытаюсь освободить значение общего экземпляра или одноэлементное значение. Кто-нибудь знает как это сделать? Нужно ли обновлять каталог? Я изучаю MEF, поэтому, пожалуйста, помогите.

Пример класса

[Export]
public class Foo
{
  public RandomProperty {get;set;}

  [ImportConstructor]
  public Foo() {}
}

Вы можете создать его примерно так:

var fooSingleton = ServiceLocator.GetInstance(typeof(Foo));

Все хорошо, но в идеале я хотел бы сделать что-то вроде этого

Container.Replace(oldFoo, newFoo);

Так что, когда я позвоню снова

var fooSingleton = ServiceLocator.GetInstance(typeof(Foo));

fooSingleton будет иметь новое значение.

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

Ответы [ 2 ]

3 голосов
/ 15 октября 2013

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

Перед вами действительно 2 варианта:

  1. Утилизируйте контейнер, предполагая, что с ним покончено. Это подходит, например, когда приложение закрывается.
  2. Измените ваши детали на временные объекты, то есть новая деталь создается каждый раз, когда вы запрашиваете одну из контейнера. Чтобы сделать это в MEF, добавьте атрибут PartCreationPolicy в Export и укажите, что он не должен использоваться совместно. Это будет выглядеть так: [PartCreationPolicy (CreationPolicy.NonShared)]. Это приведет к тому, что метод Dispose будет вызываться на ваших деталях, когда вызывается container.ReleaseExport(myExport), где myExport - это экспорт (не экспортированное значение), который сохраняется для целей выпуска.

Вот пример:

var catalog = new AggregateCatalog(// code elided);
var container = new CompositionContainer(catalog);

Lazy<IMyExportInterface> myExport = container.GetExport<IMyExportInterface>();
// later on...
container.ReleaseExport(myExport)

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

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

0 голосов
/ 25 марта 2011

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

var export = container.GetExport<Foo>();
container.ReleaseExport(export);

Скорее всего, вам потребуется обновить тип потребления (где находятся Import s), чтобы поддержать перекомпозицию.

...