Search code examples
constructorunity-container

Unity: Specify instance for single constructor parameter and auto-resolve remaining parameter types?


I have an interface INexus that is used in two different classes. The first class Nexus is the core functionality, the other is a "decorating class" NexusDecorator that takes in a INexus parameter, calls it, and adds further value to the result.

public interface INexus
{
    string Eval();
}

public class Nexus : INexus
{
    public string Eval()
    {
        return "Hello World!";
    }
}

public class NexusDecorator : INexus
{
    private readonly INexus _nexus;
    private readonly IClock _clock;
    private readonly IPrettifyer _prettifyer;

    public NexusDecorator(INexus nexus, IClock clock, IPrettifyer prettifyer)
    {
        _nexus = nexus;
        _clock = clock;
        _prettifyer = prettifyer;
    }

    public string Eval()
    {
        var s = _clock.Now() + ": " + _nexus.Eval();
        return _prettifyer.Emphasize(s); // returns somehing like "<i>12:30: Hello World!</i>"
    }
}

I use Unity to register the types:

var container = new UnityContainer();

container.RegisterType<INexus, Nexus>("base")

container.RegisterType<INexus, NexusDecorator>(
    new InjectionConstructor(
        new ResolvedParameter<INexus>("base"),
        new ResolvedParameter<IClock>(),
        new ResolvedParameter<IPrettifyer>()
        ));

The InjectionConstructor is set up with a list of instances that matches the constructor of NexusDecoratorin the right sequence, using registered types. This is great, but the only exception to the default registrations is the use of the named INexus registration that targets the Nexus class. It seems overly cumbersome having to specify how Unity should resolve what is essentially default registrations of IClockand IPrettifyer.

Is there a way to tell Unity to only override the INexusparameter of the constructor and ommit specification of the remaining parameters?

-Sigurd Garshol


Solution

  • As @tsimbalar points out, this question has been asked before:

    How do I use the Decorator Pattern with Unity without explicitly specifying every parameter in the InjectionConstructor

    It seems the short answer is: "You don't". It appears that Unity is able to automatically resolve construction of classes with only a single constructor, but once you start specifying individual parameters you're stuck with specifying them all.

    In the linked answer the OP concedes that, in his case, using InjectionFactory to explicitly new up the object graph is more readable and enables him to catch up with constructor parameter extension at compile-time.

    The down-side would appear to be that you would perhaps need to maintain a large object graph, but really: Each of the objects that are created using new could be resolved insetad if desired.