Как уничтожать объекты созданные с помощью MEF - PullRequest
1 голос
/ 02 января 2011

Привет, я использую MEF и caliburn.micro в приложении WPF. Я хотел бы знать, как я могу уничтожить объекты, созданные с помощью MEF.

Например, простая оболочка:

 [Export(typeof(IShellViewModel))]
    public class ShellViewModel : Conductor<IScreen>.Collection.OneActive, IShellViewModel
    {

        protected override void OnInitialize()
        {
            ShowLogOn();
            base.OnInitialize();
        }

        //first screen
        public void ShowLogOn()
        {
            var vm = IoC.Get<ILogOnViewModel>();
            ActivateItem(vm);
        }

        //second screen
        public void ShowMessenger(Account account)
        {
            ActiveItem.Deactivate(true);
            var vm = IoC.Get<IMessengerViewModel>();
            vm.Account = account;
            ActivateItem(vm);
        }

  }

Первый экран

[Export(typeof(ILogOnViewModel))]
public class LogOnViewModel : Screen,ILogOnViewModel
{
   User user=new User();
}

Второй экран:

  [Export(typeof(IMessengerViewModel))]
            public class MessengerViewModel : Screen, IViewModelIdentity,
                IMessengerViewModel, IHandle<Rp>, IHandle<string>
            {..}

Приложение WPF запускается с первого экрана, связанного с интерфейсом ILogOnViewModel. Затем я деактивирую этот экран и активирую второй экран, связанный с интерфейсом IMessengerViewModel.

Я проверяю использование памяти с помощью профилировщика памяти ANTS, но источник ILogOnViewModel все еще жив, а класс пользователя жив.

Я новичок в IoC, DI ... все классы, которые экспортируются с MEF, должны жить в течение всего жизненного цикла приложения WPF?

Другой пример, я создаю новое окно wpf с оконным менеджером.

[Export(typeof(IChatViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChatViewModel : Screen, IViewModelIdentity, 
    IChatViewModel, IHandle<Rp>, IHandle<DetailData>
{}

ChatViewModel - это окно WPF.

Создать экземпляр IChatViewModel:

private IWindowManager _windowManager;
var chatScreen = IoC.Get<IChatViewModel>();
_windowManager.Show(chatScreen);

Затем я закрываю (нажмите кнопку X (закрыть) в окне) Окно WPF, ChatViewModel деактивирована но этот класс все еще жив.

Существует ли способ, как убить / уничтожить это привлечение?

1 Ответ

1 голос
/ 03 января 2011

Контейнер MEF отвечает за управление временем жизни ваших экспортов, поэтому независимо от того, какой CreationPolicy используется (по умолчанию Shared), последний вызов метода Dispose контейнера избавится от любого Export экземпляры (которые оборачивают ваши фактические экземпляры класса). Кроме того, вызов Dispose для экземпляра Export также приведет к удалению фактического экземпляра класса.

Следует помнить, что GC смотрит на граф объектов и определяет, есть ли 0 или более ссылок на этот конкретный экземпляр, потому что ссылка поддерживается MEF CompositionContainer (заключенным в Export ) он не избавится от этого предмета.

Если вы используете IDisposable в ваших плагинах, например,

public interface ILogOnViewModel : IDisposable { }

И убедитесь, что при реализации шаблона dispose вы разрешаете вызывать его несколько раз:

public void Dispose(bool disposing)
{
    if (disposing && !disposed)
    {
        // Clean up?
    }
}

public void Dispose()
{
    Dispose(true);
    GC.SurpressFinalize(this);
}

Затем вы можете безопасно вызывать Dispose в своем экземпляре ILogOnViewModel реализации, не вызывая проблем при утилизации реального контейнера.

...