Share via


Registering Existing Object Instances

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

The latest Enterprise Library information can be found at the Enterprise Library site.

The Unity container exposes overloads of the following two methods that allow you to work with instances of existing objects:

  • The RegisterInstance method. This method generates a registration within the container for an existing object. You can optionally specify a name for the mapping and specify how the container will manage the lifetime of the object.
  • The BuildUp method. This method takes an existing object and applies the dependency mechanism process to it on demand. You can optionally specify a name in the overloads of this method for extensions to use.

The RegisterInstance Method

The RegisterInstance method provides a similar dependency feature to the RegisterType method (when used with the ContainerControlledLifetimeManager) in that it creates a registration that will always return a reference to the same instance of the specified object, as long as that object is in scope. While the RegisterType method with a ContainerControlledLifetimeManager automatically generates this single instance the first time your code calls it, the RegisterInstance method accepts an existing instance for which it will return references.

Note

You can use the RegisterInstance method to register simple types as well as 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.

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 will remain in the container and be returned when you execute the Resolve or ResolveAll method.

The RegisterInstance method overloads accept an additional parameter—the object instance to register—compared to the RegisterType method overloads, but the use of the registration type and an optional name are identical. The following example shows how you can use 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.

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");
'Usage
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")

Note

By default, the RegisterInstance method will register existing object instances with a container-controlled lifetime and hold on to a strong reference to the object for the life of the container. You can change this behavior if you want by using a different lifetime manager to control the creation, lifetime, and disposal of the object. For information, see Using Lifetime Managers. For details of how to create custom lifetime managers, see Creating Lifetime Managers.

Guidelines When Using the RegisterInstance Method

The following are some general guidelines and issues to be aware of when using the RegisterInstance method:

When you register an existing object, you can decide whether the container should take over lifetime management of the object. You do this by specifying the appropriate lifetime manager type:

  • If you specify the ContainerControlledLifetimeManager type, or you do not specify a lifetime type, the object will continue to exist for the lifetime of the container. When the container is disposed, it will call the Dispose method of the object and allow it to be garbage collected. Therefore, you must ensure that your code does not maintain reference to the object.
  • If you specify the ExternallyControlledLifetimeManager type, the object will continue to exist only as long as you maintain a reference to it in your code. The container will maintain only a weak reference to the object, allowing it to be disposed when no other code is holding a reference to it.

Note

Some objects, such as unmanaged components and other applications, may hold on to 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 only ever have one "owner."

When you use the RegisterInstance method to register an existing object, attribute-driven and constructor injection do not take place on that object because it has already been created outside of the influence of the Unity container. You can call the BuildUp method of the container and pass it the existing object to apply property (setter) and method call injection. However, constructor injection will never take place because the constructor will not execute.

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. The following example shows an invalid registration.

// invalid combination of registrations
myContainer.RegisterType<IMyObject, MyRealObject>();
IMyObject myExistingObject = new SomeOtherObject();
myContainer.RegisterInstance<IMyObject>(myExistingObject);
'Usage
' invalid combination of registrations
myContainer.RegisterType(Of IMyObject, MyRealObject)()
Dim myExistingObject As IMyObject = New SomeOtherObject()
myContainer.RegisterInstance(Of IMyObject)(myExistingObject)

The BuildUp Method

The BuildUp method allows you to apply the dependency injection process to an existing object on demand. The BuildUp method overloads accept the registration identifier as an interface or an object type, a reference to the existing object to process, and optionally a name for the object that container extensions can use.

The following example shows how you can use the BuildUp method to apply dependency injection to existing object instances named myDataService and myLoggingService, which implement the interface IMyService. This example uses both the generic and the non-generic overloads of the container methods.

IMyService myDataService = new DataService();
IMyService myLoggingService = new LoggingService();
IMyService builtupDataService = myContainer.BuildUp<IMyService>( myDataService);
IMyService builtupLoggingService
  = (IMyService)myContainer.BuildUp(typeof(IMyService), myLoggingService);
'Usage
Dim myDataService As IMyService = New DataService()
Dim myLoggingService As IMyService = New LoggingService()
Dim builtupDataService As IMyService = myContainer.BuildUp(Of IMyService)(myDataService)
Dim builtupLoggingService As IMyService _
  = myContainer.BuildUp(GetType(IMyService), myLoggingService)

If you have created or added extensions to the Unity container, these extensions can access and use a name that you specify when you execute the BuildUp method. This allows the extensions to change their behavior depending on the value you specify. For example, they may use the name to control how dependencies are resolved, or to control features such as event wiring or interception. The actual behavior depends on the individual extension.

The following code shows how you can execute the BuildUp method and provide a name. It uses both the generic and the non-generic overloads of the container methods.

IMyService myDataService = new DataService();
IMyService myLoggingService = new LoggingService();
IMyService builtupDataService
  = myContainer.BuildUp<IMyService>(myDataService, "Data");
IMyService builtupLoggingService
  = (IMyService)myContainer.BuildUp(typeof(IMyService), myLoggingService, "Logging");
'Usage
Dim myDataService As IMyService = New DataService()
Dim myLoggingService As IMyService = New LoggingService()
Dim builtupDataService As IMyService _
  = myContainer.BuildUp(Of IMyService)(myDataService, "Data")
Dim builtupLoggingService As IMyService _
  = myContainer.BuildUp(GetType(IMyService), myLoggingService, "Logging")