Unity behavior of a Unity container with named and unnamed registration for the same type

I am using Unity version 2.1.505.2 and I see unexpected behavior when registering UnityContainerwith default registration and named registration (s ParameterOverride) for the same interface type.

If I call twice container.Resolve<T>()- once for the specified registration and once for the default registration - I get the same instance back, whereas I expect different instances based on two different registrations.

Here is a sample code:

public interface ICage
{
    IAnimal Animal { get; }
}

public class Cage : ICage
{
    public IAnimal Animal { get; private set; }
    public Cage(IAnimal animal) { Animal = animal; }
}

public interface IAnimal
{
    string Species { get; }
}

public class Cat : IAnimal
{
    public string Species { get { return "Felis catus"; } }
}

public class Dog : IAnimal
{
    public string Species { get { return "Canis lupus"; } }
}

[TestClass]
public class UnityTest
{
    [TestMethod]
    public void MyTest()
    {
        var container = new UnityContainer();

        // Default registrations for IAnimal and ICage
        container.RegisterType<IAnimal, Cat>(new ContainerControlledLifetimeManager());
        container.RegisterType<ICage, Cage>(new ContainerControlledLifetimeManager());

        // Named registration "cage2" for ICage mapping to Cage with constructor parameter override
        container.RegisterType<ICage>(
            "cage2",
            new ContainerControlledLifetimeManager(),
            new InjectionFactory(c => c.Resolve<Cage>(new ParameterOverride("animal", new Dog()))));

        // Resolve ICage using the named registraion "cage2"
        var cage2 = container.Resolve<ICage>("cage2");
        Assert.AreEqual("Canis lupus", cage2.Animal.Species); // Assert succeeds

        // Resolve ICage using the default registration ???
        var cage = container.Resolve<ICage>();
        Assert.AreEqual("Felis catus", cage.Animal.Species); // Assert fails (Actual:<Canis lupus>)
    }
}

The second statement in the test fails because it cage.Animal.Speciesreturns "Canis lupus".

- ? , container.Resolve<ICage>("cage2") Cage, , container.Resolve<ICage>() , ?

+4
1

2 , !

"cage2".

:

var cage2 = container.Resolve<ICage>("cage2");

:

new InjectionFactory(c => c.Resolve<Cage>(new ParameterOverride("animal", new Dog()))));

c.Resolve<Cage>, Cage new Dog() IAnimal. ! :

container.RegisterType<ICage, Cage>(new ContainerControlledLifetimeManager());

! c.Resolve<Cage> Cage Dog. , ContainerControlled, , :

var cage = container.Resolve<ICage>();

, !

:

[TestClass]
public class UnityTest
{
    [TestMethod]
    public void MyTest()
    {
        var container = new UnityContainer();

        // Default registrations for IAnimal and ICage
        container.RegisterType<IAnimal, Cat>(new ContainerControlledLifetimeManager());
        container.RegisterType<ICage, Cage>(new ContainerControlledLifetimeManager());

        container.RegisterType<ICage>(
            "cage2",
            new ContainerControlledLifetimeManager(),
            new InjectionFactory(c => new Cage(new Dog())));

        // Resolve ICage using the named registraion "cage2"
        var cage2 = container.Resolve<ICage>("cage2");
        Assert.AreEqual("Canis lupus", cage2.Animal.Species); // Assert succeeds
        // Resolve default
        var cage = container.Resolve<ICage>();
        Assert.AreEqual("Felis catus", cage.Animal.Species); // Assert succeeds
    }
}
+1

Source: https://habr.com/ru/post/1671251/


All Articles