Note that there are some explanatory texts on larger screens.

plurals
  1. POUnity 2.0 and handling IDisposable types (especially with PerThreadLifetimeManager)
    primarykey
    data
    text
    <p>I know that similar question was asked several times (for example: <a href="https://stackoverflow.com/questions/987761/how-do-you-reconcile-idisposable-and-ioc">here</a>, <a href="https://stackoverflow.com/questions/1443515/unity-to-dispose-of-object">here</a>,<a href="https://stackoverflow.com/questions/1557950/di-handling-life-of-idisposable-objects">here</a> and <a href="https://stackoverflow.com/questions/2846021/perthreadlifetimemanager-in-unity">here</a>) but it was for previous versions of Unity where the answer was dependent on used <code>LifetimeManager</code> class.</p> <p>Documentation says:</p> <blockquote> <p>Unity uses specific types that inherit from the LifetimeManager base class (collectively referred to as lifetime managers) to control how it stores references to object instances and how the container disposes of these instances.</p> </blockquote> <p>Ok, sounds good so I decided to check implementation of build in lifetime managers. My conclusion:</p> <ul> <li><code>TransientLifetimeManager</code> - no handling of disposing. Container only resolves instance and it does not track it. Calling code is responsible for disposing instance.</li> <li><code>ContainerControlledLifetimeManager</code> - disposes instance when lifetime manager is disposed (= when container is disposed). Provides singleton instance shared among all containers in hiearchy.</li> <li><code>HierarchicalLifetimeManager</code> - derives behavior from <code>ContainerControlledLifetimeManager</code>. It provides "singleton" instance per container in hiearchy (subcontainers).</li> <li><code>ExternallyControlledLifetimeManager</code> - no handling of disposing. Correct behavior because container is not owner of the instance.</li> <li><code>PerResolveLifetimeManager</code> - no handling of disposing. It is generally same as <code>TransientLifetimeManager</code> but it allows reusing instance for dependency injection when resolving whole object graph.</li> <li><code>PerThreadLifetimeManager</code> - no handling of disposing as also described in MSDN. <strong>Who is responsible for disposing?</strong></li> </ul> <p>Implementation of build-in <code>PerThreadLifetimeManager</code> is:</p> <pre><code>public class PerThreadLifetimeManager : LifetimeManager { private readonly Guid key = Guid.NewGuid(); [ThreadStatic] private static Dictionary&lt;Guid, object&gt; values; private static void EnsureValues() { if (values == null) { values = new Dictionary&lt;Guid, object&gt;(); } } public override object GetValue() { object result; EnsureValues(); values.TryGetValue(this.key, out result); return result; } public override void RemoveValue() { } public override void SetValue(object newValue) { EnsureValues(); values[this.key] = newValue; } } </code></pre> <p>So disposing container does not dispose disposable instances created with this lifetime manager. Thread completion will also not dispose those instances. So who is responsible for releasing instances? </p> <p>I tried to manually dispose resolved instance in code and I found another problem. I can't teardown the instnace. RemoveValue of lifetime manager is empty - once the instance is created it is not possible to remove it from thread static dictionary (I'm also suspicious that <code>TearDown</code> method does nothing). So if you call <code>Resolve</code> after disposing the instance you will get disposed instance. I think this can be quite big problem when using this lifetime manager with threads from thread pool. </p> <p>How to correctly use this lifetime manager?</p> <p>Moreover this implementation is often reused in custom lifetime managers like PerCallContext, PerHttpRequest, PerAspNetSession, PerWcfCall, etc. Only thread static dictionary is replaced with some other construct.</p> <p>Also do I understand it correctly that handling disposable objects is dependent on lifetime manager? So the application code is dependent on used lifetime manager.</p> <p>I read that in other IoC containers dealing with temporary disposable objects is handled by subcontainers but I didn't find example for Unity - it could be probably handled with local scoped subcontainer and <code>HiearchicalLifetimeManager</code> but I'm not sure how to do it.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload