Export (0) Print
Expand All

Introduction to Unity

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 Application Block (Unity) is a lightweight, extensible dependency injection container with support for constructor, property, and method call injection. It provides developers with the following advantages:

  • It provides simplified object creation, especially for hierarchical object structures and dependencies, which simplifies application code.
  • It supports abstraction of requirements; this allows developers to specify dependencies at run time or in configuration and simplify management of crosscutting concerns.
  • It increases flexibility by deferring component configuration to the container.
  • It has a service location capability; this allows clients to store or cache the container. This is especially useful in ASP.NET Web applications where the developers can persist the container in the ASP.NET session or application.

This topic includes a series of brief sections that provide information to help you decide whether the Unity Application Block is suitable for your requirements. This topic includes the following sections:

In addition to this introductory material, the documentation contains the following topics:

  • Developing Applications Using the Unity Application Block. This topic explains how to use the Unity Application Block in your applications. It lists the system requirements, explains how to configure the application block to perform common tasks, and shows how to add application code to the application block where required. It also lists the properties of the application block.
  • Key Scenarios. This topic demonstrates how to use the application block to perform the most common operations.
  • Design of the Unity Application Block. This topic explains the decisions that went into designing the application block and the rationale behind those decisions.
  • Extending and Modifying the Unity Application Block. This topic explains how to extend the application block and how to modify the source code.
  • Deployment and Operations. This topic explains how to deploy and update the application block's assemblies and use the instrumentation exposed by the application block.
  • Unity QuickStarts. This topic walks through the QuickStart applications that demonstrate how to execute common operations in your applications.

More Information

For related information, see the following guidance:

The Unity Application Block addresses the issues faced by developers engaged in component-based software engineering. Modern business applications consist of custom business objects and components that perform specific or generic tasks within the application, in addition to components that individually address cross cutting concerns such as logging, authentication, authorization, caching, and exception handling.

The key to successfully building such applications is to achieve a decoupled or very loosely coupled design. Loosely coupled applications are more flexible and easier to maintain. They are also easier to test during development. You can mock up shims (lightweight mock implementations) of objects that have strong concrete dependencies, such as database connections, network connections, ERP connections, and rich user interface components.

Dependency injection is a prime technique for building loosely coupled applications. It provides ways to handle the dependencies between objects. For example, an object that processes customer information may depend on other objects that access the data store, validate the information, and check that the user is authorized to perform updates. Dependency injection techniques can ensure that the customer class correctly instantiates and populates all these objects, especially where the dependencies may be abstract.

The following design patterns define architectural and development approaches that simplify the process:

  • The Inversion of Control (IoC) pattern. This generic pattern describes techniques for supporting a plug-in architecture where objects can "look up" instances of other objects they require.
  • The Dependency Injection (DI) pattern. This is a special case of the IoC pattern and is an interface programming technique based on altering class behavior without the changing the class internals. Developers code against an interface for the class and use a container that injects dependent object instances into the class based on the interface or object type. The techniques for injecting object instances are interface injection, constructor injection, property (setter) injection, and method call injection.

This guidance includes the following scenarios to demonstrate the ways that you can use the Unity Application Block:

In addition, the Unity QuickStarts demonstrate many of these techniques, including a simple implementation of the Model-View-Presenter pattern and an implementation of an Event Broker service as a custom container extension.

By using dependency injection frameworks and inversion of control mechanisms, developers can generate and assemble instances of custom classes and objects that can contain dependent object instances and settings. The Unity Application Block supports this functionality, allowing developers to use techniques such as container-configured injection, constructor injection, property injection, and method call injection to generate and assemble instances of objects complete with all dependent objects and settings.

The Unity Application Block exposes two methods for registering types and mappings with the container:

  • RegisterType. This method registers a type with the container. At the appropriate time, the container will build an instance of the type you specify. This could be in response to dependency injection initiated through class attributes or when you call the Resolve method. The lifetime of the object it builds will correspond to the lifetime you specify in the parameters of the method. If you do not specify a value for the lifetime, the type is registered for a transient lifetime, which means that the container will create a new instance on each call to Resolve.
  • RegisterInstance. This method registers with the container an existing instance of a type that you specify, with the lifetime that you specify. The container will return the exiting instance during that lifetime. If you do not specify a value for the lifetime, the instance will have a container-controlled lifetime.

Container-Configured Registration of Types

As an example of using the overloads of the RegisterType and Resolve methods, the following code registers a mapping for an interface named IMyService, and specifies that the container should return an instance of the CustomerService class (which implements the IMyService interface).

IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IMyService, CustomerService>();
IMyService myServiceInstance = myContainer.Resolve<IMyService>();

Container-Configured Registration of Existing Object Instances

As an example of using the overloads of the RegisterInstance and Resolve methods, the following code registers an existing instance of a class named LoggingService that implements the interface IMyService and then retrieves that instance.

IUnityContainer myContainer = new UnityContainer();
LoggingService myExistingObject = new LoggingService();
myContainer.RegisterInstance<IMyService>(myExistingObject);
IMyService myServiceInstance = myContainer.Resolve<IMyService>();

Constructor Injection

As an example of constructor injection, if a class that developers instantiate using the Resolve method of the Unity container has a constructor that defines one or more dependencies on other classes, the Unity container will automatically create the dependent object instance specified in parameters of the constructor. For example, the following code shows a class named CustomerService that has a dependency on a class named LoggingService.

public class CustomerService
{
  public CustomerService(LoggingService myServiceInstance)
  { 
    // work with the dependent instance
    myServiceInstance.WriteToLog("SomeValue");
  }
} 

At run time, developers create an instance of the CustomerService class using the Resolve method of the container, which causes the instance generation framework to inject an instance of the concrete class LoggingService within the scope of the CustomerService class.

IUnityContainer uContainer = new UnityContainer();
CustomerService myInstance = uContainer.Resolve<CustomerService>();

Property (Setter) Injection

In addition to constructor injection, described earlier, the Unity Application Block supports property and method call injection. The following code demonstrates property injection. A class named ProductService exposes as a property a reference to an instance of another class named SupplierData (not defined in the following code). To force dependency injection of the dependent object, developers must apply the Dependency attribute to the property declaration, as shown in the following code.

public class ProductService
{
  private SupplierData supplier;

  [Dependency]
  public SupplierData SupplierDetails 
  {
    get { return supplier; }
    set { supplier = value; }
  }
} 

Now, creating an instance of the ProductService class using the Unity Application Block will automatically generate an instance of the SupplierData class and set it as the value of the SupplierDetails property of the ProductService class.


Ff649397.note(en-us,PandP.10).gifNote:
For more details of how you can use these and other features of the Unity Application Block in your applications, see Key Scenarios.

The Unity Application Block includes the following features:

  • It provides a mechanism for building (or assembling) instances of objects, which may contain other dependent object instances.
  • It exposes RegisterType methods that support configuring the container with type mappings and objects (including singleton instances) and Resolve methods that return instances of built objects that can contain any dependent objects.
  • It provides inversion of control (IoC) functionality by allowing injection of preconfigured objects into classes built by the application block. Developers can specify an interface or class type in the constructor (constructor injection), or apply attributes to properties and methods to initiate property injection and method call injection.
  • It supports a hierarchy for containers. A container may have child container(s), allowing object location queries to pass from the child out through the parent container(s).
  • It can read configuration information from standard configuration systems, such as XML files, and use it to configure the container.
  • It makes no demands on the object class definition. There is no requirement to apply attributes to classes (except when using property or method call injection), and there are no limitations on the class declaration.
  • It supports custom container extensions that developers can implement; for example, methods to allow additional object construction and container features such as caching.

Dependency injection provides opportunities to simplify code, abstract dependencies between objects, and generate dependent object instances automatically. However, the process may have a minor impact on performance, and it can increase complexity where only simple dependencies exist.

In general, you should use the Unity Application Block in the following situations:

  • Your objects and classes may have dependencies on other objects or classes.
  • Your dependencies are complex or require abstraction.
  • You want to take advantage of constructor, method, or property call injection features.
  • You want to manage the lifetime of object instances.
  • You want to be able to configure and change dependencies at run time.
  • You want to be able to cache or persist the dependencies across postbacks in a Web application.

You should not use the Unity Application Block in the following situations:

  • Your objects and classes have no dependencies on other objects or classes.
  • Your dependencies are very simple and do not require abstraction.

This release of the Unity Application Block contains several minor changes to the source code. These changes include the following:

  • Removal of all obsolete ObjectBuilder code
  • Fix for a bug when using lifetime managers with open generic types
  • Fix for a bug where the RegisterType method was overriding the RegisterInstance method
  • Performance improvement when resolving singletons
  • Exposure of some additional internal classes as public to make it easier write extensions that need to resolve dependencies in a customized way
  • Addition of try...catch blocks to improve the error messages returned when value resolution fails

These changes do not affect the API of Unity, or the way that you use it.


Show:
© 2014 Microsoft