How to: Register and Use Services

Overview

This topic describes how you typically register and obtain references to services in an application that uses the Composite Application Library and the Unity container.

Note

This topic assumes you are familiar with services. For information about services, see the Container and Services technical concept.

Prerequisites

This topic assumes that you have a solution using the Composite Application Library and that it contains a module. For information about how to create a solution using the Composite Application Library, see How to: Create a Solution Using the Composite Application Library. For information about how to create a module, see How to: Create a Module.

Steps

In an application created with the Composite Application Library, you typically write code to register services in two places:

  • In the Bootstrapper class. In the Bootstrapper class, you usually register infrastructure services for application startup or services that are consumed by multiple modules.
  • In modules classes. In modules classes, you usually register services consumed by a particular module. However, you are not restricted to this; you can also register services consumed by other modules.

Independent of the place where you write code to register services, the steps to register services are the same and depend on the container type you use. The following procedure presents generic instructions to register services with a Unity container.

To register a service with a Unity container

  1. Call the methods RegisterInstance or RegisterType on the Unity container. The following briefly describes these methods:

    • 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 existing instance during that lifetime. If you do not specify a value for the lifetime, the instance will have the default container-controlled lifetime. It will return a reference to the original object on each call to Resolve. The following code shows different ways to invoke the RegisterInstance method.

      myContainer.RegisterInstance<IMyService>(myDataService);
      myContainer.RegisterInstance<IMyService>("Email", myEmailService);
      myContainer.RegisterInstance(typeof(IMyService), "Logging", myLoggingService);
      
    • 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, 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 a new instance will be created on each call to Resolve. The following code shows different ways to invoke the RegisterType method.

      myContainer.RegisterType<IMyService, CustomerService>();
      myContainer.RegisterType<IMyService, CustomerService>("Customers");
      

      The following code shows how to register a service type using a ContainerControlledLifetimeManager lifetime manager. When you use a ContainerControlledLifetimeManager lifetime manager, Unity returns the same instance of the registered type or object each time you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes based on attributes or constructor parameters within that class. This lifetime manager effectively implements a singleton behavior for objects; you will usually want to register services this way.

      container.RegisterType<IModuleInitializerService, ModuleInitializerService>(new ContainerControlledLifetimeManager());
      

    For more information about these methods, see Setting Up the Unity Container in the Unity Application Block (Unity) documentation.

The following procedure describes how to register services in the Bootstrapper class of your application.

To register services in the Bootstrapper class

  1. Override the bootstrapper's ConfigureContainer method. The ConfigureContainer method is invoked from the bootstrapper's Run method and is the place where you typically write code to register services in the Bootstrapper class. The Run method is invoked when the application is initialized.

  2. In the ConfigureContainer method, register services in the container using the methods RegisterType or RegisterInstance as described in the procedure "To register a service with a Unity container" later in this topic.

    The following code illustrates how the Shell view is registered in the Stock Trader Reference Implementation (Stock Trader RI).

    public class StockTraderRIBootstrapper : UnityBootstrapper
    {
        protected override void ConfigureContainer()
        {
            Container.RegisterType<IShellView, Shell>();
            base.ConfigureContainer();
        }
    }
    

    Note

    The last line of the preceding method calls the method's base implementation. This is required because the base implementation registers Composite Application Library infrastructure services.
    Note that if you register a custom implementation of a Composite Application Library infrastructure service, the base implementation will not replace it. For more information about the infrastructure services registered by default, see the ConfigureContainer method in the UnityBootstrapper class.

The following procedure describes how to register services in a module class. A module class is a class that implements the IModule interface.

To register services in a module class

  1. In your module class, obtain a reference to the Unity container. To do this, you can add a parameter of type IUnityContainer to your module class's constructor, as shown in the following code. Because module classes—those that implement the IModule interface—are instantiated by the Unity container, your module class will have a Unity container instance injected through constructor injection.

    private IUnityContainer myContainer;
    
    public MyModule(IUnityContainer container)
    {
         myContainer = container;
    }
    

    Note

    For more information about automatic constructor injection, see the procedure "To declaratively obtain references to services using constructor injection" later in this topic.

  2. Add a method named RegisterServices to your class and invoke it from the Initialize method. In the RegisterServices method, register services in the container using the methods RegisterType or RegisterInstance as described in the procedure "To register a service with a Unity container" later in this topic. The following code shows how to register the service type EmployeeService with the interface IEmployeeService specifying that the service should be a singleton.

    private void RegisterServices()
    {
         myContainer.RegisterType<IEmployeeService, EmployeeService>(new ContainerControlledLifetimeManager());
    }
    

You can obtain references to services declaratively or programmatically. The following procedure describes how to declaratively obtain references to services using constructor injection.

To declaratively obtain references to services using constructor injection

  • For automatic constructor injection, you simply specify the dependent object types as parameters of the constructor. You can specify the concrete type or you can specify an interface or base class for which the Unity container contains a registered mapping.

    public class MyObject
    {
         public MyObject(IMyServiceInterface serviceInterface)
         { 
    
         }
    } 
    

Note

Unity supports other types of automatic dependency injection not covered in this guidance, including property injection and method call injection. For more information about injection in Unity, see the topics Annotating Objects for Constructor Injection and Annotating Objects for Property (Setter) Injection in the Unity documentation.

The following procedure describes how to programmatically obtain references to services.

To programmatically obtain references to services

  1. To retrieve object instances from the container, use the Resolve method of the Unity container. When you use this method without specifying a value for the optional name property, the method returns the object registered with the default mapping.

    IMyService result = myContainer.Resolve<IMyService>();
    

    To retrieve object instances from the container based on a named registration, use the Resolve method and specify a value for the name property and the registered type. The Resolve method returns the object registered with the named mapping or type registration, or it raises an exception if there is no registration that matches the specified name. Registration names are simple strings that can contain spaces, but note that they are case-sensitive.

    IMyService result = myContainer.Resolve<IMyService>("Data");
    

Note

For detailed information about how to programmatically obtain dependencies, see the topics Resolving an Object by Type and Resolving an Object by Type and Registration Name in the Unity documentation.

Next Steps

If you have not already added your views to the modules, you can do this next. For information, see the following topics:

More Information

For a complete list of How-to topics included with the Composite Application Guidance, see Development Activities.

Home page on MSDN | Community site