Object lifetime management analysis based on the Unity container

Source: Internet
Author: User

Object lifetime management for IoC containers

If you have been using the IoC container, you may have used some Object Lifetime Management models ). By managing the lifetime of an object, it is possible to reuse the object. At the same time, the container can control how to create and manage object instances.

The object lifetime management model provided by Unity is completed by using the derived class of the abstract class LifetimeManager. Unity creates a life cycle manager for each type of registration. Whenever the UnityContainer needs to create a new object instance, it first checks whether an object instance is available in the lifetime manager of this object type. If no object instance is available, UnityContainer constructs the object instance based on the configuration information and submits the object to the object lifetime manager.

LifetimeManager

LifetimeManager is an abstract class that implements the ILifetimePolicy interface. This class is used as the parent class of all built-in or custom lifetime managers. It defines three methods: GetValue-returns an object instance that has been stored in the lifetime manager. SetValue-store a new object instance to the lifetime manager. RemoveValue-delete an existing object instance from the Life Cycle manager. The default Implementation of UnityContainer does not call this method, but can be called in custom container extensions.

Unity has six built-in lifetime management models, two of which are responsible for the creation of object instances and the destruction of object instances (Disposing ).

• TransientLifetimeManager-generates a new type object instance for each request. (Default Act)
• ContainerControlledLifetimeManager-implements a Singleton object instance. When the container is Disposed, the object instance is also Disposed.
• HierarchicalifetimeManager-implement a Singleton object instance. But the sub-container does not share the parent container instance, but creates a Singleton object instance for the word container. When the container is Disposed, the object instance is also Disposed.
• ExternallyControlledLifetimeManager-implemented Singleton object instance, but the container only holds the weak reference of this object, so the lifetime of this object is controlled by external reference.
• PerThreadLifetimeManager-generates Singleton object instances for each thread, which is implemented through ThreadStatic.
• PerResolveLifetimeManager-similar to TransientLifetimeManager, a new type object instance is generated for each request. The difference is that the object instance can be reused in the BuildUp process.
Code Double

Copy codeThe Code is as follows: public interface IExample: IDisposable
{
Void SayHello ();
}

Public class Example: IExample
{
Private bool _ disposed = false;
Private readonly Guid _ key = Guid. NewGuid ();

Public void SayHello ()
{
If (_ disposed)
{
Throw new ObjectDisposedException ("Example ",
String. Format ("{0} is already disposed! ", _ Key ));
}

Console. WriteLine ("{0} says hello in thread {1 }! ", _ Key,
Thread. CurrentThread. ManagedThreadId );
}

Public void Dispose ()
{
If (! _ Disposed)
{
_ Disposed = true;
}
}
}

TransientLifetimeManager

TransientLifetimeManager is the default Life Cycle manager of Unity. The internal implementation is empty, which means that a new object instance is created and returned every time the container is created. Of course, the container is not responsible for storing and destroying the object instance.

Copy codeThe Code is as follows: private static void TestTransientLifetimeManager ()
{
IExample example;
Using (IUnityContainer container = new UnityContainer ())
{
Container. RegisterType (typeof (IExample), typeof (Example ),
New TransientLifetimeManager ());

// Each one gets its own instance
Container. Resolve <IExample> (). SayHello ();
Example = container. Resolve <IExample> ();
}
// Container is disposed but Example instance still lives
// All previusly created instances weren't disposed!
Example. SayHello ();

Console. ReadKey ();
}

ContainerControlledLifetimeManager

ContainerControlledLifetimeManager provides a Singleton registered object instance for UnityContainer and its sub-containers. It only creates a new object instance when requesting a registration type for the first time. The object instance will be stored in the lifetime manager and will be reused all the time. When the container is destructed, the life cycle manager calls RemoveValue to destroy the stored object.

Singleton object instances correspond to each object type registration. If the same object type is registered multiple times, a single instance is created for each registration.

Copy codeThe Code is as follows: private static void TestContainerControlledLifetimeManager ()
{
IExample example;
Using (IUnityContainer container = new UnityContainer ())
{
Container. RegisterType (typeof (IExample), typeof (Example ),
New ContainerControlledLifetimeManager ());

IUnityContainer firstSub = null;
IUnityContainer secondSub = null;

Try
{
FirstSub = container. CreateChildContainer ();
SecondSub = container. CreateChildContainer ();

// All containers share same instance
// Each resolve returns same instance
FirstSub. Resolve <IExample> (). SayHello ();

// Run one resolving in other thread and still receive same instance
Thread thread = new Thread (
() => SecondSub. Resolve <IExample> (). SayHello ());
Thread. Start ();

Container. Resolve <IExample> (). SayHello ();
Example = container. Resolve <IExample> ();
Thread. Join ();
}
Finally
{
If (firstSub! = Null) firstSub. Dispose ();
If (secondSub! = Null) secondSub. Dispose ();
}
}

Try
{
// Exception-instance has been disposed with container
Example. SayHello ();
}
Catch (ObjectDisposedException ex)
{
Console. WriteLine (ex. Message );
}

Console. ReadKey ();
}

The HierarchicalLifetimeManager class is derived from ContainerControlledLifetimeManager and inherits all the behaviors of the parent class. The difference from the parent class lies in the lifetime Manager Behavior in the sub-container. ContainerControlledLifetimeManager shares the same object instance, including in sub-containers. HierarchicalLifetimeManager is shared only in the same container, and each sub-container has its own object instance.

Copy codeThe Code is as follows: private static void TestHierarchicalLifetimeManager ()
{
IExample example;
Using (IUnityContainer container = new UnityContainer ())
{
Container. RegisterType (typeof (IExample), typeof (Example ),
New HierarchicalLifetimeManager ());

IUnityContainer firstSub = null;
IUnityContainer secondSub = null;

Try
{
FirstSub = container. CreateChildContainer ();
SecondSub = container. CreateChildContainer ();

// Each subcontainer has its own instance
FirstSub. Resolve <IExample> (). SayHello ();
SecondSub. Resolve <IExample> (). SayHello ();
Container. Resolve <IExample> (). SayHello ();
Example = firstSub. Resolve <IExample> ();
}
Finally
{
If (firstSub! = Null) firstSub. Dispose ();
If (secondSub! = Null) secondSub. Dispose ();
}
}

Try
{
// Exception-instance has been disposed with container
Example. SayHello ();
}
Catch (ObjectDisposedException ex)
{
Console. WriteLine (ex. Message );
}

Console. ReadKey ();
}

ExternallyControlledLifetimeManager

The life cycle of the object instance in ExternallyControlledLifetimeManager will be subject to external implementation control of UnityContainer. The life cycle Manager stores a WeakReference of the provided object instance. Therefore, if the external implementation of the UnityContainer container does not have a strong reference to the object instance, the object instance will be recycled by GC. When you request this object type instance again, a new object instance is created.

Copy codeThe Code is as follows: private static void TestExternallyControlledLifetimeManager ()
{
IExample example;
Using (IUnityContainer container = new UnityContainer ())
{
Container. RegisterType (typeof (IExample), typeof (Example ),
New ExternallyControlledLifetimeManager ());

// Same instance is used in following
Container. Resolve <IExample> (). SayHello ();
Container. Resolve <IExample> (). SayHello ();

// Run garbate collector. Stored Example instance will be released
// Beacuse there is no reference for it and LifetimeManager holds
// Only WeakReference
GC. Collect ();

// Object stored targeted by WeakReference was released
// New instance is created!
Container. Resolve <IExample> (). SayHello ();
Example = container. Resolve <IExample> ();
}

Example. SayHello ();

Console. ReadKey ();
}

This result proves that the strong reference still exists. Why? If you find the reason, please let me know. Thank you.

PerThreadLifetimeManager

The PerThreadLifetimeManager model provides the "single instance per Thread" function. All object instances are stored in the ThreadStatic set. The container does not track the creation of the object instance and is not responsible for the Dipose.

Copy codeThe Code is as follows: private static void TestPerThreadLifetimeManager ()
{
IExample example;
Using (IUnityContainer container = new UnityContainer ())
{
Container. RegisterType (typeof (IExample), typeof (Example ),
New PerThreadLifetimeManager ());

Action <int> action = delegate (int sleep)
{
// Both calluse same instance per thread
Container. Resolve <IExample> (). SayHello ();
Thread. Sleep (sleep );
Container. Resolve <IExample> (). SayHello ();
};

Thread thread1 = new Thread (a) => action. Invoke (int) ));
Thread thread2 = new Thread (a) => action. Invoke (int) ));
Thread1.Start (50 );
Thread2.Start (50 );

Thread1.Join ();
Thread2.Join ();

Example = container. Resolve <IExample> ();
}

Example. SayHello ();

Console. ReadKey ();
}

PerResolveLifetimeManager

PerResolveLifetimeManager is a special built-in model of Unity. Because Unity uses separate logic to process registration-type Per-Resolve lifecycles. Each time you request a Resolve type object, UnityContainer creates and returns a new object instance.

Copy codeThe Code is as follows: private static void TestPerResolveLifetimeManager ()
{
IExample example;
Using (IUnityContainer container = new UnityContainer ())
{
Container. RegisterType (typeof (IExample), typeof (Example ),
New PerResolveLifetimeManager ());

Container. Resolve <IExample> (). SayHello ();
Container. Resolve <IExample> (). SayHello ();

Example = container. Resolve <IExample> ();
}

Example. SayHello ();

Console. ReadKey ();
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.