Удаление компонентов, введенных через конструктор, без ограничений времени жизни в Autofac - PullRequest
1 голос
/ 10 июля 2020

Я не могу понять, почему мои компоненты никогда не удаляются / не выпускаются в Autofa c. У меня есть стандартное приложение WPF, которое начинается в app.xaml.cs, разрешая MainVM, который является синглтоном, и показывает MainWindow с DataContext из MainVM.

Затем я работаю в основном с Внедрение конструктора моих зарегистрированных компонентов, которые являются одиночными или (по умолчанию) instancePerDependency, каждый раз создавались новыми. Или у меня иногда есть фабрики, чтобы передать какие-то специальные параметры.

Например, фабрики выглядят так:

public delegate MyComponent Factory(string parameter1, int parameter2);

Инъекция выглядит так:

public MainVM(MyComponent.Factory createMyComponent)
...
public void makeNewComponent()
{
  var myComponent = this.createMyComponent("test", 1);
  myComponent.DoStuff();
}

А это Вот как регистрируются мои компоненты:

containerBuilder.RegisterType<T>().OnActivated(args => (args.Instance as IInitializable)?.Initialize());

builder.RegisterType<MyComponent>().As<IMyComponent>().OnActivated(args => (args.Instance as IInitializable)?.Initialize());

// This will never be called in my code: .OnRelease(instance => (instance as IInitializable)?.Uninitialize())*/;

Теперь давайте представим, что у меня есть много таких моделей представлений, которые создаются внутри других моделей представлений, поэтому у нас есть как MainVM -> MyComponent -> OtherComponent , и после завершения операции я хочу, чтобы они утилизировались (или просто как-то исчезли из памяти), вызывали Dispose() или вызывали событие OnRelease из Autofa c. Подойдет любой из них.

Но моя проблема в том, что я не использую этот шаблон:

using(var scope = container.BeginLifetimeScope())

'Потому что я не работаю внутри одного метода от {до}. Мне нужно, чтобы мой компонент жил внутри объекта во многих методах, и после того, как, скажем, я удаляю ViewModel1 из своего стека представления, я хочу, чтобы все, что создано внутри этого ViewModel1, избавляло / освобождало его дочерние элементы. Что заставляет компоненты думать, что их можно утилизировать? Как я могу сказать, что модель просмотра больше не нужна, если она не создана в пределах времени жизни?

1 Ответ

0 голосов
/ 10 июля 2020

Вы не должны заботиться о классах, которые не реализуют IDisposable. Несмотря на то, что их экземпляры создаются контейнером Autofa c, объекты будут автоматически объединены в GC, как только на них не будет ссылок с корнем G C (например, представление закрыто, и все ссылки на него null -ed). Это влияет на весь граф зависимостей - не имеет значения, насколько он глубок.

Если у вас do есть IDisposable объектов в вашей настройке, контейнер, конечно, будет содержать ссылки на них , потому что ему нужно избавиться от этих объектов. Однако вы все равно можете контролировать, как это происходит.

Для этого вы можете использовать Owned<T> экземпляры ваших IDisposable зависимостей.

Рассмотрим свой пример:

class MainVM 
{
    private readonly Owned<IMyComponent> _myComponent;

    public MainVM(Owned<IMyComponent> myComponent) => _myComponent = myComponent;

    public void DoStuff() => _myComponent.Value.DoStuff();

    public void OnViewClosed() => _myComponent.Dispose();
}

class MyComponent : IMyComponent, IDisposable
{
    public MyComponent(IOtherComponent otherComponent) { /* ... */ }
}

class OtherComponent : IOtherComponent, IDisposable
{
}

Теперь, когда вызывается метод OnViewClosed, собственный экземпляр MyComponent будет удален, включая все не разделяемые, одноразовые зависимости MyComponent - то есть OtherComponent в нашем примере.

Прочтите о собственных экземплярах в документации.

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