Resolving All Objects of a Particular Type
When you want to obtain a list of all the registered objects of a specific type, you can use the ResolveAll method. The two overloads of this method accept either an interface or a type name, and they return an instance of IEnumerable that contains references to all registered objects of that type that are not default mappings. The list returned by the ResolveAll method contains only named instance registrations. The ResolveAll method is useful if you have registered multiple object or interface types using the same type but different names. You can also use the params to provide constructor overrides for the ResolveAll calls.
The ResolveAll Method Overloads
The following table shows the overloads of the ResolveAll method. You can only request a list of objects using the object type. The API for the Unity container contains both generic and non-generic overloads of this method so that you can use it with languages that do not support the generics syntax.
Method |
Description |
---|---|
ResolveAll<T>( params ResolverOverride[] resolverOverrides) |
Returns a list of IEnumerable<T>, where T is the type registered as a non-default mapping with the container as the type T and where params provide any constructor overrides for the ResolveAllcalls. |
ResolveAll(Type t, params ResolverOverride[] resolverOverrides) |
Returns a list of IEnumerable<object>, where object is the type registered as a non-default mapping with the container as the type t and where params provide any constructor overrides for the ResolveAllcalls. |
Note
It is important to remember that you must register type mappings using a name in addition to the registration type (which identifies the registration) if you want to be able to retrieve a list of mapped types using the ResolveAll method. In other words, you must use overloads of the RegisterType and RegisterInstance methods that take a name (as a String) and the dependency type, or specify the name in your configuration of type mappings. This behavior is by design. The expectation is that you will either use only named mappings or use only default mappings.
If you register a named type or a named type mapping more than once using the same type and name, only the last registration remains in the container and is applied when you execute the ResolveAll method. If the container does not contain any named (non-default) mappings for the specified type, it will return null (in C#) or Nothing (in Visual Basic).
Using the ResolveAll Method
The following examples show how you can retrieve a list of all registered types for a specific registration type. They use the run-time methods of the container to register the types it will resolve. For more information about how you can configure Unity with type registrations and mappings, see Configuring Unity.
// Create container and register types using a name for each one
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IMyService, DefaultService>();
myContainer.RegisterType<IMyService, DataService>("Data");
myContainer.RegisterType<IMyService, LoggingService>("Logging");
// Retrieve a list of non-default types registered for IMyService
// List will only contain the types DataService and LoggingService
IEnumerable<IMyService> serviceList = myContainer.ResolveAll<IMyService>();
'Usage
' Create container and register types using a name for each one
Dim myContainer As IUnityContainer = New UnityContainer()
myContainer.RegisterType(Of IMyService, DefaultService)()
myContainer.RegisterType(Of IMyService, DataService)("Data")
myContainer.RegisterType(Of IMyService, LoggingService)("Logging")
' Retrieve a list of non-default types registered for IMyService
' List will only contain the types DataService and LoggingService
Dim serviceList As IEnumerable(Of IMyService) = myContainer.ResolveAll(Of IMyService)
Alternatively, you can use the non-generic methods of the container to achieve the same result, except that the return value this time is an IEnumerable list of type Object.
// Create container and register types using a name for each one
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType(typeof(MyServiceBase), typeof(DefaultService));
myContainer.RegisterType(typeof(MyServiceBase), typeof(DataService), "Data");
myContainer.RegisterType(typeof(MyServiceBase), typeof(LoggingService), "Logging");
// Retrieve a list of non-default types registered for MyServiceBase
// List will only contain the types DataService and LoggingService
foreach(Object mapping in myContainer.ResolveAll(typeof(MyServiceBase)))
{
MyServiceBase myService = (MyServiceBase)mapping;
}
'Usage
' Create container and register types using a name for each one
Dim myContainer As IUnityContainer = New UnityContainer()
myContainer.RegisterType(GetType(MyServiceBase), GetType(DefaultService))
myContainer.RegisterType(GetType(MyServiceBase), GetType(DataService), "Data")
myContainer.RegisterType(GetType(MyServiceBase), GetType(LoggingService), "Logging")
' Retrieve a list of non-default types registered for MyServiceBase
' List will only contain the types DataService and LoggingService
For Each mapping As Object In myContainer.ResolveAll(GetType(MyServiceBase))
Dim myService As MyServiceBase = CType(mapping, MyServiceBase)
Next
Resolving All Generic Types by Name
You can use the ResolveAll method with generic types, just as you do with non-generic types, to retrieve an enumerable list of resolved instances for all of the named mappings for a generic type. However, all of the registrations or mappings must resolve to a type that has the same set of type arguments, and you must specify these type arguments in the call to the ResolveAll method.
Note
Where you resolve a closed type, and there are both unbound and closed registrations in the container that potentially match the type you are resolving, Unity will preferentially use the registration or type mapping defined for the closed generic type rather than the unbound one.
For more information see Resolving All Objects of a Particular Type.