Registration by Convention
This topic explains how to use registration by convention to register multiple types with the container automatically by using a set of rules and conventions.
This topic contains the following sections that explain registration by convention:
- TheRegisterTypesMethod
- Identifying the Types to Register Automatically
- Specifying Mapping Behavior
- Specifying Default and Named Registrations
- Specifying the Lifetime Manager to Use
- Specying Injection Behavior
- Specifying Whether to Overwrite Existing Mappings
The RegisterTypes Method
To register multiple types using registration by convention you use the RegisterTypes method. The parameters to this method enable you to specify which types to register, what mappings to create, whether to use named regsitrations, which lifetime manager to use, and any injection members to use. The full signatures of the RegisterTypes extension methods are shown here:
public static IUnityContainer RegisterTypes(
this IUnityContainer container,
IEnumerable<Type> types,
Func<Type, IEnumerable<Type>> getFromTypes = null,
Func<Type, string> getName = null,
Func<Type, LifetimeManager> getLifetimeManager = null,
Func<Type, IEnumerable<InjectionMember>> getInjectionMembers = null,
bool overwriteExistingMappings)
public static IUnityContainer RegisterTypes(
this IUnityContainer container,
RegistrationConvention convention,
bool overwriteExistingMappings = false)
The RegistrationConvention class is an abstract class. You can extend this class to create your own, resusable conventions.
The following sample illustrates using the RegisterTypes method to register multiple types in the Unity container.
using (var container = new UnityContainer())
{
container.RegisterTypes(
AllClasses.FromLoadedAssemblies(),
WithMapping.MatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled);
}
Identifying the Types to Register Automatically
Use the types parameter of the RegisterTypes method to specify the list types to register with the container. You can provide this list yourself or use the AllClasses helper class to build the list of types for you. The following table lists the methods of the AllClasses helper class.
Method |
Description |
Platform |
---|---|---|
FromAssemblies |
Takes as parameters the list of assemblies to scan. Returns all visible, non-abstract classes from this list of assemblies. Optionally, control how exceptions are handled when getting types from an assembly by using the skipOnError parameter. |
Desktop and Windows Store apps |
FromAssembliesInBasePath |
Returns all visible, non-abstract classes from all assemblies located in the base folder of the current application domain. Optionally, control how exceptions are handled when getting types from an assembly by using the skipOnError parameter. Optionally control whether to load system assemblies, dynamic assemblies, and Unity assemblies by using the includeSystemAssemblies, includeDynamicAssemblies, and includeUnityAssemblies parameters. |
Desktop |
FromLoadedAssemblies |
Returns all visible, non-abstract classes from all assemblies loaded in the current application domain. Optionally, control how exceptions are handled when getting types from an assembly by using the skipOnError parameter. Optionally control whether to load system assemblies, dynamic assemblies, and Unity assemblies by using the includeSystemAssemblies, includeDynamicAssemblies, and includeUnityAssemblies parameters. |
Desktop |
FromApplication |
Returns all visible, non-abstract classes from all assemblies loaded in the install location of the application. Optionally, control how exceptions are handled when getting types from an assembly by using the skipOnError parameter. Optionally control whether to load system assemblies, dynamic assemblies, and Unity assemblies by using the includeSystemAssemblies, includeDynamicAssemblies, and includeUnityAssemblies parameters. |
Windows Store apps |
Remarks
If you try to use the AllClasses.FromAssembliesInBasePath helper method in a web application, it will not load the assemblies from the bin folder in the web application. To load these assemblies, you should the BuildManager.GetReferencedAssemblies method to obtain a list of assemblies in the bin folder and pass this collection to the AllClasses.FromAssemblies helper method.
Specifying Mapping Behavior
Use the optional getFromTypes parameter of the RegisterTypes method to control what mappings to create in the container for the automatically registered types. The WithMapping helper class provides a set of mapping strategies to use. The following table lists the mapping strategies defined in the WithMapping class.
Strategy |
Description |
---|---|
AllInterfaces |
Creates a mapping from each interface implemented by the registered type. |
AllInterfacesInTheSameAssembly |
Creates a mapping from each interface implemented by the registered type where the interface is in the same assembly as the registered type. |
MatchingInterface |
Creates mappings where there are registered types with matching interfaces. A matching interface is identified using the following naming convention: an interface named ITenantStore matches a type named TenantStore. |
NoTypes |
No mappings are created. |
Specifying Default and Named Registrations
Use the optional getName parameter of the RegisterTypes method to control whether to create named or default registrations in the container. The WithName helper class provides a set of naming strategies to use. The following table lists the naming strategies defined in the WithName class.
Strategy |
Description |
---|---|
TypeName |
Uses the name of the registered type as the name of the registration. |
Default |
Uses default registrations (with no name). |
Specifying the Lifetime Manager to Use
Use the optional getLifetime parameter of the RegisterTypes method to control which lifetime manager to use for the registrations. The WithLifetime helper class provides a way to select from the available lifetime managers. The following table lists the lifetime managers defined in the WithLifetime class.
Lifetime manager |
Available in Windows Store apps |
---|---|
ContainerControlled |
Yes |
Custom<T> |
Yes |
ExternallyControlled |
Yes |
Hierarchical |
Yes |
None |
Yes |
PerResolve |
Yes |
PerThread |
No |
Transient |
Yes |
Specifying Injection Behavior
Use the optional getInjectionMembers parameter of the RegisterTypes method to control which types the container should inject into the registered types. The container will attempt to inject the injection members whenever you resolve a type from the container. You should be sure that you can inject the injection members into all of types registered in the container. For more information, see the discussion of registration by convention in Chapter 3, “Dependency Injection with Unity” in the Developer’s Guide for Unity.
Specifying Whether to Overwrite Existing Mappings
Use this parameter to control the behavior of the RegisterTypes method if the parameters to this method cause an existing mapping in the container to be overwritten. The existing mapping may have been created by a previous call to to register a type or types or during the current call to the RegisterTypes method. If this parameter is set to false, the method throws an DuplicateTypeMappingException exception if it detects an attempt to overwrite an existing mapping. If the parameter is set to true, the method overwrites the existing mapping with a new mapping based on the other parameters to the method. The default value for this parameter is false.
Note
The RegisterTypes method uses reflection to identify types to register and map in the Unity container. You should sort the list of types passed to the RegisterTypes method to guarantee the repeatable behavior if the overwriteExistingMappings parameter is true.