Question

I'm trying to use Unity to resolve dependencies based on a name/identifier I pass when I resolve.

Consider the following object graph:

internal interface IFoo
{
    Type GetTypeOfInnerClass();
}

internal class Foo : IFoo
{
    private readonly Abstract abstractImplementation;

    public Foo(Abstract abstractImplementation)
    {
        this.abstractImplementation = abstractImplementation;
    }

    public Type GetTypeOfInnerClass()
    {
        return abstractImplementation.GetType();

    }
}

internal abstract class Abstract
{

}

internal class Bar : Abstract
{

}

I have three tests:

    [TestMethod]
    public void TestUnity()
    {
        using (var container = new UnityContainer())
        {
            container.RegisterType<IFoo, Foo>();
            container.RegisterType<Abstract, Bar>();

            var foo = container.Resolve<IFoo>();

            Assert.AreEqual("Bar", foo.GetTypeOfInnerClass().Name);
        }
    }

    [TestMethod]
    public void TestUnityWithIdentifier()
    {

        using (var container = new UnityContainer())
        {
            string identifier = Guid.NewGuid().ToString();

            container.RegisterType<Abstract, Bar>(identifier);

            var abstractClass = container.Resolve<Abstract>(identifier);

            Assert.AreEqual("Bar", abstractClass.GetType().Name);
        }
    }

    [TestMethod]
    public void TestNestledConstructionWithIdentifier()
    {

        using (var container = new UnityContainer())
        {
            string identifier = Guid.NewGuid().ToString();

            container.RegisterType<Abstract, Bar>(identifier);
            container.RegisterType<IFoo, Foo>(identifier);

            var foo = container.Resolve<IFoo>(identifier); //Exception occurs

            Assert.AreEqual("Bar", foo.GetTypeOfInnerClass().Name);
        }
    }

}

The first two passes nicely but the third throws an exception : System.InvalidOperationException: The current type, Test.Abstract, is an abstract class and cannot be constructed. Are you missing a type mapping?

Unity can't find the mapping because it doesn't use the identifier when resolving. How can I get unity to use the identifier when resolving nestled dependencies?

Was it helpful?

Solution

If I understand your intentions right you are trying to register a type for IFoo and provide a specific implementation of Abstract to it's constructor – the Bar class (that’s why you’re using the identifier). In order to do that you could try the following:

    [TestMethod]
    public void TestNestedConstructionWithIdentifier()
    {

        using (var container = new UnityContainer())
        {
            string identifier = Guid.NewGuid().ToString();

            container.RegisterType<Abstract, Bar>(identifier);
            container.RegisterType<IFoo, Foo>(identifier, new InjectionConstructor(new ResolvedParameter<Abstract>(identifier)));

            var foo = container.Resolve<IFoo>(identifier);

            Assert.AreEqual("Bar", foo.GetTypeOfInnerClass().Name);
        }
    }

As far as I know it’s not possible to tell Unity something like: I’m registering types with the same identifier so when I’m using this identifier to resolve one of those types use types registered with the same identifier while resolving – hope you understand what I mean here ;) The identifier doesn’t group or associate the registered types. Also remember that if you register a type mapping with an identifier you don’t have a default registration. So if you do something like:

container.RegisterType<Abstract, Bar>(identifier);

and then call:

container.Resolve<Abstract>();

you’ll get an exception.

I hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top