0
votes

We use Unity dependency injection. We have a class that needs a type passed to it's constructor.

public interface ITest
{
}

public class Test : ITest
{
    public Test(Type myType)
    {

    }
}

In the container boostrapper we register our type:

public static IUnityContainer Start()
{
    IUnityContainer container = UnityInversionOfControlContainer.RegisterContainer();

    container.RegisterType<ITest, Test>();

    return container;
}

we resolve like so:

object actual = container.Resolve<ITest>(new ParameterOverride("myType", typeof(string)));

this give the following error:

Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "ITest", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The type String cannot be constructed. You must configure the container to supply this value.

At the time of the exception, the container was:

Resolving Test,(none) (mapped from Belastingdienst.Omvormers.Mapper.ITest, (none)) Resolving parameter "myType" of constructor Test(System.Type myType) Resolving System.String,(none) ---> System.InvalidOperationException: The type String cannot be constructed. You must configure the container to supply this value.

It appears that unity wants to resolve the type via container, and pass in an instance of the type, but I do need the Type.

Thoughts anyone?

3
Do you mean container.Resolve<ITest>...? It seems not to work with parameters of type Type, I tried with stringand it worked fine. Might be a bug in unity.Haukinger
try registering myType and typeof(string) as an instance not a typeHaitham Shaddad

3 Answers

1
votes

The answer was contained in the code from the link posted by Haukinger:

object actual = 
    container.Resolve<IDatarecordSerializer>(
        new ParameterOverride(
            "type", 
             new InjectionParameter(typeof(string))
        )
    );
0
votes

In fact, Unity explicitly treats Type values in a ParameterOverride not as literal values but as types that should themselves be resolved. And then it tries to resolve an instance of type string and fails, obviously.

ParameterOverride stores the value in a InjectionParameterValue instance, which it turn interpretes Type different from other types.

See lines 77ff in InjectionParameterValue.cs

I'd try creating an issue with Unity, but I guess it's more of a feature than a bug...

In the meantime, hide the Type from Unity by changing the type of the dependency to something like this:

class HiddenType
{
    public Type Type
    {
        get;
    }

    public HiddenType( Type type )
    {
        Type = type;
    }
}
0
votes

The simpler way out is to register a factory :

given:

internal interface ITyped
{
    Type Type { get; }
}

internal class Typed : ITyped
{
    public Typed(Type type)
    {
        Type = type;
    }

    public Type Type { get; }
}

Fty:

internal class TypedFactory : ITypedFactory
{
    public ITyped Create(Type type)
    {
        return new Typed(type);
    }
}

internal interface ITypedFactory
{
    ITyped Create(Type type);
}


container.RegisterType<ITypedFactory, TypedFactory>();

Assert.AreEqual(
    container.Resolve<ITypedFactory>().Create(typeof(string)).Type,
     typeof(string));

is not rocket science but is simple, obvious and easier to debug