Unity RegisterInstance IDisposable объектов - PullRequest
9 голосов
/ 16 марта 2011

Unity 2.0:

По умолчанию RegisterInstance использует ContainerControlledLifetimeManager.Когда контейнер Unity удаляется, он вызывает Dispose для экземпляра (если IDisposable).

В моем случае это не то, что я хочу.Экземпляр принадлежит и расположен другим классом;Единство должно просто вставить ссылку.Поэтому я использовал:

container.RegisterInstance(instance, new ExternallyControlledLifetimeManager());

Документация Unity (в разделе «Понимание менеджеров времени жизни») гласит:

Использование метода RegisterInstance для регистрации существующего объекта приводит к тому же поведению, как если бы вытолько что зарегистрировал пожизненный контейнер с помощью RegisterType.Поэтому рекомендуется не использовать метод RegisterInstance для регистрации существующего объекта при использовании менеджеров времени жизни не по умолчанию, за исключением потока, в котором был вызван RegisterInstance.

Что это значит?

В том же разделе также говорится:

Если вы зарегистрировали существующий экземпляр объекта с помощью метода RegisterInstance, контейнер возвращает один и тот же экземпляр для всех вызовов Resolve или ResolveAll иликогда механизм зависимости внедряет экземпляры в другие классы, при условии, что выполняется одно из следующих условий:

  • Вы указали управляемый контейнером диспетчер времени жизни
  • Вы использовали диспетчер времени жизни по умолчанию
  • Вы разрешаете в том же контексте, в котором вы зарегистрировали экземпляр при использовании другого менеджера времени жизни.

Я попытался разрешить в другом потоке после использования RegisterInstance с ExternallyControlledLifetimeManager,Если бы это сработало - я получил экземпляр синглтона.

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

Для ясности, я всегда хочу, чтобы контейнер Unity внедрял зарегистрированный мной экземпляр независимо от потока и т. Д., И я не хочу, чтобы Unity распоряжалась им.Я делаю это правильно?

Ответы [ 2 ]

5 голосов
/ 17 марта 2011

Будьте в курсе ExternallyControlledLifetimeManager. Вы по-прежнему должны хранить ссылку на экземпляр где-то за пределами контейнера. Потеряв ссылку, вы можете потерять экземпляр, потому что ExternallyControlledLifetimeManager содержит только WeakReference. Если у вас нет нормальной ссылки Сборщик мусора может собрать ваш экземпляр. Проверьте пример в моем блоге.

2 голосов
/ 17 марта 2011

Я думаю, ты хороший. Все комментарии для каждого потока имеют значение только тогда, когда вы используете PerThreadLifetimeManager, который вы не используете. Это просто неуклюжая формулировка в части статьи MSDN.

Это не стандартная терминология, но в данной статье под контекстом они подразумевают нечто, определенное конкретным менеджером продолжительности жизни. Для PerThreadLifetimeManager ваш контекст - это ваш поток. Для HierarchicalLifetimeManager ваш контекст является конкретным контейнером в вашей иерархии контейнеров.

Для ExternallyControlledLifetimeManager нет определенного контекста, поэтому вы можете полностью игнорировать заметку.

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

...