Resolving Instances of Types Using Unity

Microsoft Enterprise Library 5.0

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

This topic discusses the methods that Unity provides for resolving types and creating instances of types. It also describes how you can resolve instances of Enterprise Library objects and your own custom types. The topics are the following:


Note:
Other topics in this section show how you can inject resolved instances into your own custom classes, and how you can create instances of Enterprise Library objects directly. For more information, see Injecting Resolved Types into Other Classes and Creating Application Block Objects Directly.


The Unity Resolve Method

The following table describes some of the more commonly used overloads of the Unity container methods that return object instances, and are suitable for use with Enterprise Library objects.

Method signature

Description

Resolve<T>()

Returns a concrete instance of the type that is registered for the generic type T.

Resolve<T>(string name)

Returns a concrete instance of the type that is registered for the generic type T and has the specified name.

Resolve(Type t)

Returns as an Object type a concrete instance of the type that is registered for the type t.

Resolve(Type t, string name)

Returns as an Object type a concrete instance of the type that is registered for the type t and has the specified name.

Resolving Instances of Enterprise Library Types

The following code shows how an application that uses the Data Access Application Block can resolve a Database object defined as the default provider for the block in configuration. This code assumes that you have saved a reference to the default container that holds the Enterprise Library configuration in the variable named container.

C# Copy Code
Database db = container.Resolve<Database>();
Visual Basic Copy Code
Dim db As Database = container.Resolve(Of Database)()

If you want to specify a named instance of the target class, as defined in the application configuration, you specify the name in the call to the Resolve method. For example, the following code resolves a concrete instance of the Database class defined in configuration with the name Northwind.

C# Copy Code
Database db = container.Resolve<Database>("Northwind");
Visual Basic Copy Code
Dim db As Database = container.Resolve(Of Database)("Northwind")

An alternative approach when using the Resolve method, if you did not maintain a reference to the default container, is to access it through the static Current property of the EnterpriseLibraryContainer class and use the GetInstance method, as shown here.

However, be aware that is some cases, such as ASP.NET applications, this approach may result in a different instance of the target type each time you resolve it if the containers are independent or are configured in different ways.

C# Copy Code
Database db = EnterpriseLibraryContainer.Current.GetInstance<Database>("Northwind");
Visual Basic Copy Code
Dim db As Database = EnterpriseLibraryContainer.Current.GetInstance(Of Database)("Northwind")

Note:
Notice that the return type of the Current property is IServiceLocator. This is used to provide container-independence in Enterprise Library if you decide to use an alternative dependency injection mechanism to access Enterprise Library configuration information. The IServiceLocator interface exposes several overloads of the GetInstance method that you can use to resolve instances of registered classes and types. For more information, see CommonServiceLocator on CodePlex.

Resolving Instances of Your Own Custom Types

You can register types and mappings between interfaces and base classes and concrete types in the Unity container either by adding these to your application configuration, or by calling the RegisterType and RegisterInstance methods of the container in your code. You can then resolve concrete instances of these types in your application code.

For example, you can register a concrete type named CustomerService that implements the IMyService interface and provides some service to your application using the following code. This code assumes that you have saved a reference to the container in the variable named container.

C# Copy Code
container.RegisterType<IMyService, CustomerService>();
Visual Basic Copy Code
container.RegisterType(Of IMyService, CustomerService)()

Then you can resolve the concrete type using the following code.

C# Copy Code
IMyService myServiceInstance = container.Resolve<IMyService>();
Visual Basic Copy Code
Dim myServiceInstance As IMyService = container.Resolve(Of IMyService)()

This returns an instance of the CustomerService type, though you can change the actual type returned at run time by changing the mapping in the container. Alternatively, you can register multiple registrations or mappings for an interface or base class with different names and specify the name when you resolve the type.

The following code shows how you can register an existing instance of an object and a type mapping that will create a new instance of an object (both of which implement the same interface, IMyService), with the container and then retrieve these objects using the registration names.

C# Copy Code
// Create an instance of a service you want to use. Alternatively, this
// may have been created by another process and passed to your application
LoggingService myLoggingService = new LoggingService();

// Register the existing object instance with the container
container.RegisterInstance<IMyService>("Logging", myLoggingService);

// Register a mapping for another service your application will use
container.RegisterType<IMyService, myDataService>("DataService");

// When required, retrieve an instance of these services
IMyService theDataService = container.Resolve<IMyService>("DataService");
IMyService theLoggingService = container.Resolve<IMyService>("Logging");
Visual Basic Copy Code
' Create an instance of a service you want to use. Alternatively, this
' may have been created by another process and passed to your application
Dim myLoggingService As New LoggingService()

' Register the existing object instance with the container
container.RegisterInstance(Of IMyService)("Logging", myLoggingService)

' Register a mapping for another service your application will use
container.RegisterType(Of IMyService, myDataService)("DataService")

' When required, retrieve an instance of these services
Dim theDataService As IMyService = container.Resolve(Of  IMyService)("DataService")
Dim theLoggingService As IMyService = container.Resolve(Of  IMyService)("Logging")

The container also provides features that allow you to control the lifetime of objects that you resolve through it. In the preceding code, the RegisterInstance method will, by default, register the logging service as a singleton whereas the RegisterType method (which creates a mapping in the container) will register the type so that the container creates and returns a new instance each time. However, you can override these settings if required.

You can see from this how useful and powerful the dependency injection techniques enabled by the Unity dependency injection mechanism can be. For information about how you can use Unity to create instances of your own objects and services and how to use it as a stand-alone dependency injection mechanism, see Unity Dependency Injection and Interception.

For information about how you can configure Unity with type registrations and mappings, see Configuring Unity.

For information about the design of the Enterprise Library integration with Unity, and how you can extend this integration, see The Dependency Injection Model.