Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity RegisterInstance of IDisposable objects

Unity 2.0:

By default RegisterInstance uses the ContainerControlledLifetimeManager. When the Unity container is disposed, it calls Dispose on the instance (if IDisposable).

In my case that's not what I want. The instance is owned by and disposed by another class; Unity should just inject the reference. So I used:

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

The Unity documentation (under Understanding Lifetime Managers) states:

Using the RegisterInstance method to register an existing object results in the same behavior as if you just registered the lifetime container with RegisterType. Therefore, it is recommended that you do not use the RegisterInstance method to register an existing object when using the non-default lifetime managers except for the thread in which the RegisterInstance was invoked.

What does this mean?

The same section also states:

If you registered an existing instance of an object using the RegisterInstance method, the container returns the same instance for all calls to Resolve or ResolveAll or when the dependency mechanism injects instances into other classes, provided that one of the following is true:

  • You have specified a container-controlled lifetime manager
  • You have used the default lifetime manager
  • You are resolving in the same context in which you registered the instance when using a different lifetime manager.

I tried resolving in a different thread after using RegisterInstance with ExternallyControlledLifetimeManager, and it worked - I got the singleton instance.

My code matches an example in the Creating Instance Registrations section. I want to make sure I understand the context caveats, though.

To be clear, I always want the Unity container to inject the instance I registered regardless of thread, etc. and I do not want Unity to dispose of it. Am I doing this correctly?

like image 326
TrueWill Avatar asked Mar 16 '11 19:03

TrueWill


2 Answers

Be aware of ExternallyControlledLifetimeManager. You must still hold the reference to the instance somewhere outside of the container. Once you lose the reference you can lose the instance because ExternallyControlledLifetimeManager holds only WeakReference. If you don't have normal reference Garbage collector can collect your instance. Check example on my blog.

like image 112
Ladislav Mrnka Avatar answered Nov 07 '22 01:11

Ladislav Mrnka


I think you are good. All the per-thread comments only matters when you are using PerThreadLifetimeManager, which you are not using. It's just clumsy wording on the MSDN article part.

This is not a standard terminology, but in this article by context they mean something defined by a particular life time manager. For PerThreadLifetimeManager your context is your thread. For HierarchicalLifetimeManager your context is a particular container in your container hierarchy.

For ExternallyControlledLifetimeManager there is no particular context, so you can ignore the note in question completely.

As a side note, make sure that you don't dispose your instances while you still expect the container to resolve them. If you do, your resolve request will either return a different instance than you expected, or throw an exception, depending on whether the container can construct your type or not.

like image 36
Andrew Savinykh Avatar answered Nov 07 '22 01:11

Andrew Savinykh