Stuart Hemming
Stuart Hemming

Reputation: 1663

DependencyResolver doesn't Resolve dependencies. Why?

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

Answers (1)

Stuart Hemming
Stuart Hemming

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

Related Questions