Reputation: 1663
I'm using Unity as my IoC in a project.
UnityConfig is setup like this...
public static class UnityConfig
{
private static readonly IUnityContainer container = new UnityContainer();
public static void ConfigureIoCContainer()
{
My.Composition.Builder.Compose(container);
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
/// <summary>
/// Gets the configured Unity container.
/// </summary>
public static IUnityContainer GetConfiguredContainer()
{
return container;
}
}
My.Composition.Builder.Compose() does this ...
public static void Compose(IUnityContainer container)
{
var types = new List<Type>();
types.AddRange(Services.Interface.Builder.GetTypes(container));
types.AddRange(Services.Builder.GetTypes(container));
// ... lots more assemblies referenced here
var distinctTypes = types.Distinct();
container.RegisterTypes(distinctTypes, WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.PerResolve);
}
Now, in the 2 assemblies referenced above, this I return 3 types; IConfigUow
, ISecurityUow
and IResourceUow
from the first and ConfigUow
, SecurityUow
and ResourceUow
from the second.
If I put a breakpoint at the line after My.Composition.Builder.Compose(container)
in UnityConfig is called and have a look at the list of registered types I can see all that I should...
{Microsoft.Practices.Unity.ContainerRegistration}
LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
MappedToType: {Name = "ConfigUow" FullName = "My.Services.Security.ConfigUow"}
Name: null
RegisteredType: {Name = "IConfigUow" FullName = "My.Services.Interface.Security.IConfigUow"}
{Microsoft.Practices.Unity.ContainerRegistration}
LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
MappedToType: {Name = "SecurityUow" FullName = "My.Services.Security.SecurityUow"}
Name: null
RegisteredType: {Name = "ISecurityUow" FullName = "My.Services.Interface.Security.ISecurityUow"}
{Microsoft.Practices.Unity.ContainerRegistration}
LifetimeManager: {Microsoft.Practices.Unity.PerResolveLifetimeManager}
LifetimeManagerType: {Name = "PerResolveLifetimeManager" FullName = "Microsoft.Practices.Unity.PerResolveLifetimeManager"}
MappedToType: {Name = "ResourceUow" FullName = "My.Services.Localization.ResourceUow"}
Name: null
RegisteredType: {Name = "IResourceUow" FullName = "My.Services.Interface.Localization.IResourceUow"}
However, if I let the next line execute to set the DependencyResolver and call
DependencyResolver.Current.GetService<IConfigUow>();
a value of null
is returned. Calling
DependencyResolver.Current.GetService<ISecurityUow>();
works and returns an instance of SecurityUow
. Attempting to resolve IResourceUow
also fails.
For the life of me I can't see what I'm doing wrong. Anyone have any ideas?
UPDATE
OK, so by calling container.Resolve(IConfigUow)
I got an exception that was being masked by the DependencyResolver.
The error suggested that I was missing a type mapping. The constructor for ConfigUow
looks like this...
public ConfigUow(ICrudRepo<AM.Configuration> crudRepo = null) : base(crudRepo)
{
CrudRepo = crudRepo ?? DependencyResolver.Current.GetService<IConfigRepo>();
Ctx = CrudRepo.GetContext();
}
I was unaware that I needed to explicitly call RegisterType()
for types that use generics.
So, all I needed to do was register the appropriate type like this...
container.RegisterType(typeof (ICrudRepo<>), typeof (CrudRepo<>));
And it all worked.
For future readers, these pages proved helpful...
Upvotes: 2
Views: 2039
Reputation: 1663
The answer was that the DependencyResolver was masking the fact that the IoC container was throwing an exception.
Having discovered that it wasn't too hard to fix the problem. Readers are invited to look at the UPDATE to the original question to see what it was I had to fix and how I did it.
Upvotes: 2