Creating Instance Registrations

Microsoft Enterprise Library 5.0

DropDown image DropDownHover image Collapse image Expand image CollapseAll image ExpandAll image Copy image CopyHover image

This topic explains how to register existing objects in the container that you can resolve in your application. This technique is useful if you already have an instance of an object that you have previously created and want Unity to manage its lifetime, or if you want Unity to inject that object into other objects that it is resolving.

The RegisterInstance method registers an existing instance with the container. You specify the instance type and optional lifetime in the parameter list. The container will return the specified existing instance for the duration of the specified lifetime. The RegisterInstance method overloads are very similar to the RegisterType method overloads, but they accept an additional parameter, the object instance to register. The use of the registration type and an optional name are identical for the two methods.

When resolving types with dependencies, instances of objects added to the container with the RegisterInstance method act just like those registered through RegisterType. The RegisterType method with a ContainerControlledLifetimeManager automatically generates this single instance the first time your code calls it, while the RegisterInstance method accepts an existing instance for which it will return references. If you do not specify a lifetime manager, the container will use a ContainerControlledLifetimeManager and it will return a reference to the original object on each call to Resolve.

This topic contains the following sections, which explain the use of the RegisterInstance method:

Registering an Existing Object Instance of an Interface or Type to a Container

Instance registration is similar to type registration, except that instead of the container creating the instance you first create the instance directly and then use the RegisterInstance method to add that instance to the container. Therefore, the container does not need to create the instance on the first Resolve request. The LifetimeManager still controls the lifetime of the object, including when object instances are created and disposed, and the container returns the existing instance for the duration of the specified lifetime. For example, you first create the instance but the lifetime manager determines whether that instance is a singleton or has a per-thread lifetime.


Note:
By default, the RegisterInstance method registers existing object instances with a container-controlled lifetime, ContainerControlledLifetimeManager, and holds onto a strong reference to the object for the life of the container. You can change this behavior by using a different lifetime manager to control the lifetime and disposal of the object. For more information, see Understanding Lifetime Managers. For information about how to create custom lifetime managers, see Creating Lifetime Managers.


The Unity container exposes overloads of the RegisterInstance method that allow you to register dependency injection mappings that return references to a single existing instance of an object. Each of these methods accepts a type parameter that identifies the object interface or type and an existing instance of the object. Optionally, you can provide a name to disambiguate instances when there is more than one registration for the same type. In all cases you must first create or obtain a reference to a container.

Once you have a reference to the proper container, call the RegisterInstance method of that container to register the existing object. Specify as the registration type an interface that the target object implements, an object type from which the target object inherits, or the concrete type of the target object.

The following example creates a default (unnamed) registration for an object of type EmailService that implements the IMyService interface.

C# Copy Code
EmailService myEmailService = new EmailService();
myContainer.RegisterInstance<IMyService>(myEmailService);
Visual Basic Copy Code
Dim myEmailService As New EmailService()
myContainer.RegisterInstance(Of IMyService)(myEmailService)

The registration type controls how you will retrieve objects from the container. It is the type that you will specify when you call the Resolve or ResolveAll method to retrieve the concrete object instance. In this case, IMyService theDataService = myContainer.Resolve<IMyService>().

If you do not want to map the existing object type to an interface or base class type, you can specify the actual concrete type, myEmailService, for the registered type, EmailService, as shown in the following example.

C# Copy Code
myContainer.RegisterInstance<EmailService>(myEmailService);
Visual Basic Copy Code
myContainer.RegisterInstance(Of EmailService)(myEmailService)

If you want to create more than one existing object registration using the same registered type, you can create named (non-default) mappings by specifying a name as a parameter, such as "Email" as shown in the following example.

C# Copy Code
myContainer.RegisterInstance<EmailService>("Email", myEmailService);
Visual Basic Copy Code
myContainer.RegisterInstance(Of EmailService)("Email", myEmailService)

Note:
In general, you should never need to specify the same registered type in calls to the RegisterType and RegisterInstance methods. In other words, if you register a mapping for IMyObject using the RegisterType method, you should avoid using IMyObject as the registration type parameter of the RegisterInstance method. You are likely to get unexpected behavior because type mapping occurs before instances are resolved.


If you want to manage the instance lifetime, provide a reference to the existing object and an instance of the lifetime manager. The following example creates a default (unnamed) externally managed registration using an interface, IMyService, as the registered type and specifies the lifetime manager by providing the ExternallyControlledLifetimeManager class as a parameter of the RegisterInstance method.

C# Copy Code
EmailService myEmailService = new EmailService();
myContainer.RegisterInstance<IMyService>(myEmailService, 
                            new ExternallyControlledLifetimeManager());
Visual Basic Copy Code
Dim myEmailService As New EmailService()
myContainer.RegisterInstance(Of IMyService)(myEmailService, _ 
                            New ExternallyControlledLifetimeManager())

Note:
When you use the RegisterInstance method to register an existing object, dependency injection will not take place on that object because it has already been created outside of the influence of the Unity container. You can force property and method call injection to occur by passing the object through the BuildUp method, but you cannot force constructor injection to occur because the class constructor will never execute for an existing object. For information about using constructor, property, or method call injection techniques, see Registering Injected Parameter and Property Values .


The following example uses the RegisterInstance method to register existing instances of objects that implement the IMyService interface. This example uses both the generic and the non-generic overloads of the container methods and shows the Resolve method call for each instance.

C# Copy Code
DataService myDataService = new DataService();
EmailService myEmailService = new EmailService();
LoggingService myLoggingService = new LoggingService();

// Create container and register existing object instance
IUnityContainer myContainer = new UnityContainer();

myContainer.RegisterInstance<IMyService>(myDataService);
myContainer.RegisterInstance<IMyService>("Email", myEmailService);
myContainer.RegisterInstance(typeof(IMyService), "Logging", myLoggingService);

// Retrieve an instance of each type
IMyService theDataService = myContainer.Resolve<IMyService>();
IMyService theEmailService = myContainer.Resolve<IMyService>("Email");
IMyService theLoggingService
  = (IMyService)myContainer.Resolve(typeof(IMyService), "Logging");
Visual Basic Copy Code
Dim myDataService As New DataService()
Dim myEmailService As New EmailService()
Dim myLoggingService As New LoggingService()

' Create container and register existing object instance
Dim myContainer As IUnityContainer = New UnityContainer()
myContainer.RegisterInstance(Of IMyService)(myDataService)
myContainer.RegisterInstance(Of IMyService)("Email", myEmailService)
myContainer.RegisterInstance(GetType(IMyService), "Logging", myLoggingService)

' Retrieve an instance of each type
Dim theDataService As IMyService = myContainer.Resolve(Of IMyService)()
Dim theEmailService As IMyService = myContainer.Resolve(Of IMyService)("Email")
Dim theLoggingService As IMyService = myContainer.Resolve(GetType(IMyService), "Logging")

You can use the RegisterInstance method to register simple types and more complex or custom types. For example, you can register String values such as database connection strings with the container and have them injected into your code as required.


Note:
If you register a type more than once using the RegisterInstance method (in other words, if you register more than one instance of the same type), only the last one you register remains in the container and is returned when you execute the Resolve or ResolveAll method.

Using a Lifetime Manager with the RegisterInstance Method

The lifetime manager you specify when you register an existing object enables you to manage object lifetimes. If you do not specify a lifetime manager for your instance registration, by default, the object instances returned by the container when you use the RegisterInstance method have a container-controlled lifetime. If you want to specify the lifetime of the object, specify a lifetime manager when you call the RegisterInstance method.


Note:
Some objects, such as unmanaged components and other applications, may hold onto references to an object that you pass to the RegisterInstance method. In this case, you should use the ExternallyControlledLifetimeManager. However, you should always design your code so that disposable objects always have only one "owner."


The most common scenario is to create an instance that behaves like a singleton, so that the container creates the object the first time you call Resolve and then returns the same instance for all subsequent calls to Resolve for as long as the container is in scope. You can specify one of the following Unity Built-In Lifetime Managers types or your custom type when you call the RegisterInstance method:

  • ContainerControlledLifetimeManager
  • ExternallyControlledLifetimeManager
  • HierarchicalLifetimeManager

Note:
It is not appropriate to use either PerResolveLifetimeManager or TransientLifetimeManager with RegisterInstance since they both create a new instance on every call to resolve.


The following example summarizes how you can use the RegisterInstance method with a lifetime manager to specify the container behavior. It shows how you can generate both default and named mappings when you register an existing object. This example uses the generic overloads of the container methods.

C# Copy Code
IUnityContainer myContainer = new UnityContainer();

// Register an existing object as a default (un-named) registration with 
// the default container-controlled lifetime. 
myContainer.RegisterInstance<IMyObject>(MyRealObject);
// Following code will return a singleton instance of MyRealObject
// Container will take over lifetime management of the object
myContainer.Resolve<IMyObject>();

// Register an existing object as a named registration with the default
// container-controlled lifetime.
myContainer.RegisterInstance<IMyObject>("MySingleton", MyRealObject);
// Following code will return a singleton instance of MyRealObject
// Container will take over lifetime management of the object
myContainer.Resolve<IMyObject>("MySingleton");

// Same as above, but specify the default lifetime manager
myContainer.RegisterInstance<IMyObject>("MySingleton", MyRealObject, new ContainerControlledLifetimeManager());
// Following code will return a singleton instance of MyRealObject
// Container will take over lifetime management of the object
myContainer.Resolve<IMyObject>("MySingleton");

// Register an existing object as a default (un-named) registration 
// with an externally controlled lifetime.
myContainer.RegisterInstance<IMyObject>(MyRealObject, new ExternallyControlledLifetimeManager());
// Following code will return a singleton instance of MyRealObject
// Container will hold only a weak reference to the object
myContainer.Resolve<IMyObject>();

// Register an existing object as a named registration 
// with an externally controlled lifetime.
myContainer.RegisterInstance<IMyObject>("MySingleton", MyRealObject, new ExternallyControlledLifetimeManager());
// Following code will return a singleton instance of MyRealObject
// Container will hold only a weak reference to the object
myContainer.Resolve<IMyObject>("MySingleton");

// Register an existing object as a named registration 
// with a per thread lifetime.
myContainer.RegisterInstance<IMyObject>("MySingleton", MyRealObject, new PerThreadLifetimeManager());
// Following code will return a singleton instance of MyRealObject
// Container will hold only a weak reference to the object
myContainer.Resolve<IMyObject>("MySingleton");
Visual Basic Copy Code
Dim myContainer As IUnityContainer = New UnityContainer()

' Register an existing object as a default (un-named) registration with 
' the default container-controlled lifetime. 
myContainer.RegisterInstance(Of IMyObject)(MyRealObject)
' Following code will return a singleton instance of MyRealObject
' Container will take over lifetime management of the object
myContainer.Resolve(Of IMyObject)()

' Register an existing object as a named registration with the default
' container-controlled lifetime.
myContainer.RegisterInstance(Of IMyObject)("MySingleton", MyRealObject)
' Following code will return a singleton instance of MyRealObject
' Container will take over lifetime management of the object
myContainer.Resolve(Of IMyObject)("MySingleton")

' Same as above, but specify the default lifetime manager
myContainer.RegisterInstance(Of IMyObject)("MySingleton", MyRealObject, new ContainerControlledLifetimeManager())
' Following code will return a singleton instance of MyRealObject
' Container will take over lifetime management of the object
myContainer.Resolve(Of IMyObject)("MySingleton")

' Register an existing object as a default (un-named) registration 
' with an externally controlled lifetime.
myContainer.RegisterInstance(Of IMyObject)(MyRealObject, new ExternallyControlledLifetimeManager())
' Following code will return a singleton instance of MyRealObject
' Container will hold only a weak reference to the object
myContainer.Resolve(Of IMyObject)()

' Register an existing object as a named registration 
' with an externally controlled lifetime.
myContainer.RegisterInstance(Of IMyObject)("MySingleton", MyRealObject, new ExternallyControlledLifetimeManager())
' Following code will return a singleton instance of MyRealObject
' Container will hold only a weak reference to the object
myContainer.Resolve(Of IMyObject)("MySingleton")
' Register an existing object as a named registration 
' with a per thread lifetime.
myContainer.RegisterInstance(Of IMyObject)("MySingleton", MyRealObject, new PerThreadLifetimeManager())
' Following code will return a singleton instance of MyRealObject
' Container will hold only a weak reference to the object
myContainer.Resolve(Of IMyObject)("MySingleton")

For more information about lifetime managers see Understanding Lifetime Managers.

Summary of the RegisterInstance Overloads

The following table summarizes the method overloads you can use to register existing object instances with the container at run time.

Method

Description

RegisterInstance<TInterface>(TInterface instance)

Registers a default instance mapping with the container so that it returns the specified instance when a Resolve method requests an instance of the type TInterface (which can be an implemented interface instead of the actual type). The container takes over the lifetime of the instance.

RegisterInstance<TInterface>(TInterface instance, LifetimeManager lifetime)

Registers a default instance mapping with the container so that it returns the specified instance when a Resolve method requests an instance of the type TInterface (which can be an implemented interface instead of the actual type). Also registers the specified LifetimeManager instance with the container to manage the lifetime of the returned object.

RegisterInstance<TInterface>(String name, TInterface instance)

Registers a named instance mapping with the container so that it returns the specified instance when a Resolve method requests an instance of the type TInterface (which can be an implemented interface instead of the actual type) and the specified name. The container takes over the lifetime of the instance. Names are case sensitive.

RegisterInstance<TInterface>(String name, TInterface instance, LifetimeManager lifetime)

Registers a named instance mapping with the container so that it returns the specified instance when a Resolve method requests an instance of the type TInterface (which can be an implemented interface instead of the actual type) and the specified name. Names are case sensitive. Also registers the specified LifetimeManager instance with the container to manage the lifetime of the returned object.

RegisterInstance(Type t, Object instance)

Registers a default instance mapping with the container so that it returns the specified instance when a Resolve method requests an instance of the type t (which can be an implemented interface instead of the actual type). The container takes over the lifetime of the instance.

RegisterInstance(Type t, Object instance, LifetimeManager lifetime)

Registers a default instance mapping with the container so that it returns the specified instance when a Resolve method requests an instance of the type t (which can be an implemented interface instead of the actual type). Also registers the specified LifetimeManager instance with the container to manage the lifetime of the returned object.

RegisterInstance(Type t, String name, Object instance)

Registers a named instance mapping with the container so that it returns the specified instance when a Resolve method requests an instance of the type t (which can be an implemented interface instead of the actual type) and the specified name. Names are case sensitive. Also registers the specified LifetimeManager instance with the container to manage the lifetime of the returned object.

RegisterInstance(Type t, String name, Object instance, LifetimeManager lifetime)

Registers a named instance mapping with the container so that it returns the specified instance when a Resolve method requests an instance of the type t (which can be an implemented interface instead of the actual type) and the specified name. Names are case sensitive. Also registers the specified LifetimeManager instance with the container to manage the lifetime of the returned object.

More Information

For more information about the techniques discussed in this topic, see the following topics: