0

Short question: how can I achieve the same functionality of TypedParameter as described in the Autofac documentation section Passing Parameters to Resolve in Unity?

Some background: we need to resolve inherited classes that rename the constructor parameter of the base class. This parameter can't be resolved and must be passed in. We know that the inherited classes will only have types that can be resolved and the one base class constructor parameter.

kind regards, Jef

Jef Patat
  • 999
  • 1
  • 10
  • 26
  • 1
    [Prevent injecting runtime data into your injection constructors](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99). This leads to all sorts of complication as you are already noticing. – Steven Mar 21 '17 at 17:39
  • @Steven I actually happen to have read your post earlier today while searching for a solution for my real problem, but it didn't get me closer to a good solution. My question is related to another question I posted earlier http://stackoverflow.com/questions/42908224/initialize-hierarchical-tree-viewmodels-with-unity I think it's good practice to have the model wrapped in the VM. I could create a INodeVMFactory but then I'm just moving the same basic problem around. We might switch to another container, but first we need a good grip on the problem. – Jef Patat Mar 21 '17 at 18:56

1 Answers1

0

You can create your own TypedParameter like this:

internal class Program
{
    static void Main( string[] args )
    {
        var container = new UnityContainer();
        container.RegisterType<IInterface, Implementation>();

                    // this will be created with this MyLogger instance
        var instance = container.Resolve<IInterface>( new TypedParameter( typeof(ILogger), new MyLogger() ) );
    }
}

internal class TypedParameter : ResolverOverride
{
    private readonly Type _type;
    private readonly InjectionParameterValue _value;

    public TypedParameter( Type type, object value )
    {
        _type = type;
        _value = InjectionParameterValue.ToParameter( value );
    }

    public override IDependencyResolverPolicy GetResolver( IBuilderContext context, Type dependencyType )
    {
        ConstructorArgumentResolveOperation currentOperation = context.CurrentOperation as ConstructorArgumentResolveOperation;
        if ( currentOperation != null )
        {
            var parameter = currentOperation.TypeBeingConstructed.GetConstructors().Single().GetParameters().Single( x => x.Name == currentOperation.ParameterName );
            if (parameter.ParameterType == _type)
                return _value.GetResolverPolicy( dependencyType );
        }

        return null;
    }
}

// note that this is not registered with unity, is has to come from TypedParameter
internal class MyLogger : ILogger
{
}

internal interface ILogger
{
}

internal interface IInterface
{
}

internal class Implementation : IInterface
{
    public Implementation( ILogger logger )
    {
    }
}

Not production ready, but it works if the type constructed only has one constructor. But you have to be careful because these overrides act on all dependencies created in one Resolve call.

Haukinger
  • 10,420
  • 2
  • 15
  • 28