My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
TypedNamedAndKeyedServices  
Many implementations of the same service can be differentiated using names and keys.
Autofac2
Updated Aug 17, 2010 by nicholas...@gmail.com

Autofac provides three typical ways to identify services.

By Type

The default method of describing a service is as a type.

builder.Register<OnlineState>().As<IDeviceState>();

This example associates the IDeviceState typed service with the OnlineState component. Instances of the component can be retrieved using the service type with the Resolve() method:

var r = container.Resolve<IDeviceState>();

Typed services also work with Autowiring.

By Name

Services can be further identified using a service name. Using this technique, the Named() registration method replaces As().

builder.Register<OnlineState>().Named<IDeviceState>("online");

To retrieve a named service, the ResolveNamed() method is used:

var r = container.ResolveNamed<IDeviceState>("online");

In versions of Autofac prior to 2.3, ResolveNamed() is simply an overload of Resolve().

Named services are simply keyed services that use a string as a key, and so the techniques described in the next section apply equally to named services.

By Key

Using strings as component names is convenient in some cases, but in others we may wish to use keys of other types. Keyed services provide this ability.

For example, an enum may describe the different device states in our example:

public enum DeviceState { Online, Offline }

Each enum value corresponds to an implementation of the service:

public class OnlineState : IDeviceState { }

The enum values can then be registered as keys for the implementations as shown below.

var builder = new ContainerBuilder();
builder.RegisterType<OnlineState>().Keyed<IDeviceState>(DeviceState.Online);
builder.RegisterType<OfflineState>().Keyed<IDeviceState>(DeviceState.Offline);
// Register other components here

Resolving Explicitly

The implementation can be resolved explicitly with ResolveKeyed():

var r = container.ResolveKeyed<IDeviceState>(DeviceState.Online);

This does however result in using the container as a Service Locator, which is discouraged. As an alternative to this pattern, the IIndex type is provided.

In versions of Autofac prior to 2.3, ResolveKeyed() is simply an overload of Resolve().

Resolving with an Index

Autofac.Features.Indexed.IIndex<K,V> is a relationship type that Autofac implements automatically. Components that need to choose between service implementations based on a key can do so by taking a constructor parameter of type IIndex<K,V>.

public class Modem : IHardwareDevice
{
    IIndex<DeviceState, IDeviceState> _states;
    IDeviceState _currentState;

    public Modem(IIndex<DeviceState, IDeviceState> states)
    {
         _states = states;
         SwitchOn();
    }

    void SwitchOn()
    {
         _currentState = _states[DeviceState.Online];
    }
}

In the SwitchOn() method, the index is used to find the implementation of IDeviceState that was registered with the DeviceState.Online key.


Sign in to add a comment
Powered by Google Project Hosting