WCF, Unity: разборные одноразовые экземпляры - PullRequest
6 голосов
/ 20 апреля 2011

мы настроили службу WCF, которая использует контейнер Unity для разрешения экземпляров для управления командами Exchange 2010 Powershell. Мы определили интерфейс IExchangePowershell, который имеет конкретную реализацию, реализующую IDisposable. Через некоторое время мы столкнулись с проблемой, что мы больше не можем выполнять команды powershell, поскольку сервер сказал, что уже открыто слишком много сеансов powershell. Кажется, что мы никогда не избавлялись от наших экземпляров PowerShell. Метод Dispose () конкретного Powershell позаботится о закрытии пространства выполнения и сеанса. Когда я вызываю это в методах репозитория, мы больше не получаем ошибок.

((IDisposable)this.powershell).Dispose();

Теперь, конечно, я не хочу явно вызывать dispose в каждом методе репозитория. Я думал, что единство может позаботиться об этом. Наш поставщик экземпляров WCF делает это:

public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
    container.Teardown(instance);
}

Но в действительности это не относится к экземплярам IExchangePowershell. Ты хоть представляешь, как я могу автоматически избавиться от этих экземпляров?

Ответы [ 2 ]

10 голосов
/ 20 апреля 2011

Это действительно хорошо известная проблема в Unity. TearDown метод ничего не делает . Если вы хотите использовать TearDown, вы должны создать собственное расширение контейнера.

Я написал статью об использовании менеджеров времени жизни объектов в Unity и их влиянии на утилизацию. Если вы используете значения по умолчанию TransientLifetimeManager или PerResolveLifetimeManager, Unity даже не будет отслеживать существование ваших объектов, поэтому он не сможет вызвать Dispose. Единственные менеджеры времени жизни, которые вызывают Dispose на разрешенных экземплярах, это ContainerControlledLifetimeManager (он же синглтон) и HierarchicalLifetimeManager. Dispose вызывается, когда распорядитель времени жизни расположен.

Решением для вас является либо использование приведения и обработки Dispose вручную, как вы уже сделали, либо переключение на HiearchicalLifetimeManager и создание нового подконтейнера для каждого входящего запроса WCF. Каждый подконтейнер будет обрабатывать только один запрос и будет располагать разрешенные объекты с высоким сроком службы.

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

0 голосов
/ 20 апреля 2011

Ответ зависит от того, как вы регистрируете свой тип / экземпляр с единицей.Стандартная реализация Teardown ничего не делает.

Если вы регистрируете тип, то Unity не сохраняет ссылку на экземпляр, который он создает, - вы сами можете управлять его временем жизни и распоряжаться им.Если вы регистрируете экземпляр, то время жизни экземпляра управляется единицей и сохраняется до тех пор, пока вы не утилизируете контейнер.

Ссылка ниже помогает немного лучше понять управление жизненным циклом: http://msdn.microsoft.com/en-us/library/ff648098.aspx

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

(извините, я не знаком с WCF, поэтому я не уверен, какой экземпляр предоставляют в этомконтекст)

...