Skip to content

Resolving a type with container.Resolve and ResolverOverrides does not use a separate BuilderContext when resolving dependencies #230

Open
@RonHeck

Description

@RonHeck

Description

I have a wrapper type Foo with ctor Foo(IAbc,IXyz). I want to resolve Foo using UnityContainer.Resolve. I provide a ResolverOverride for IAbc to the call. When the container resolves the dependencies of types constructor, it uses the BuilderContext of Foo to resolve IXyz which also includes the ResolverOverride for IAbc. Regarding inversion of control this seems to be wrong as the caller of Resolve<Foo>() should not know how IXyz is resolved and therefore should not "accidentally" influence resolving IXyz (e.g. if IXyz resolves to a type that depends on IAbc.

To Reproduce

Please provide UnitTest in the form of:

[TestMethod]
public void Should_Resolve_Dependency_Without_Override()
{
    //***** arrange *****
    var unityContainer = new UnityContainer();
    unityContainer.RegisterType<IXyz, Xyz>();
    unityContainer.RegisterType<IAbc, Abc>();
    var dummyAbc = new OverrideAbc();

    //***** act *****
    var foo = unityContainer.Resolve<Foo>(new DependencyOverride<IAbc>(dummyAbc));

    //***** assert *****
    // TestContext.WriteLine("foo.Abc - " + foo.Abc.Text);
    // TestContext.WriteLine("foo.Xyz.Abc - " + foo.Xyz.Abc.Text);
    Assert.That(foo.Abc, Is.Not.SameAs(foo.Xyz.Abc));
}
        
private interface IAbc
{
    string Text { get; }
}
        
private class Abc : IAbc
{
    public string Text { get; } = "A am an registered type";
}
        
private class OverrideAbc : IAbc
{
    public string Text { get; } = "A am an override";
}
        
private interface IXyz
{
    public IAbc Abc { get; }
}
        
private class Xyz : IXyz
{
    public IAbc Abc { get; }

    /// <summary>
    /// Creates a new instance of <see cref="Xyz"/>.
    /// </summary>
    public Xyz(IAbc abc)
    {
         Abc = abc;
    }
}

private class Foo
{
     public IAbc Abc { get; }
     public IXyz Xyz { get; }

     /// <summary>
     /// Creates a new instance of <see cref="Foo"/>.
     /// </summary>
     public Foo(IAbc abc, IXyz xyz)
     {
          Abc = abc;
          Xyz = xyz;
     }
}

Additional context

Used Version 5.11.8 of unity container nuget to verify. Test was written with NUnit so may it has to be adjust to the used test framework.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions