Search code examples
c#unity-container

Unity - chained dependencies with overridden parameter


I need to override parameter on a chained dependencies. My overridden parameter has to be passed to first and second instantiated classes.

So my client class need an instance of IA with a custom env parameter (not know at startup). And the constructor of IA need an instance of IB with the same custom env parameter.

So here is the code of my two classes :

class A : IA
{
    IB _b;
    AppEnv _env;

    public A(IB b, AppEnv env)
    {
        _b = b;
        _env = env;
    }

    void DoStuff();
}

class B : IB
{
    AppEnv _env;

    public A(AppEnv env)
    {
        _env = env;
    }

    void DoStuff();
}

And here is the code of my client :

var env = new... // "good" env, with runtime values
var a = container.Resolve<IA>(new ParameterOverride("env", env));

Instance of IA has the "good" env parameter. But how can I pass this parameter to instance of IB ?

My Unity configuration look like this :

var defaultEnv = new ... // default env object
container.RegisterType<IB, B>(new InjectionConstructor(defaultEnv));
container.RegisterType<IA, A>(new InjectionConstructor(defaultEnv));

Solution

  • If you don't want to change inheritance, I think you shouldnt use static resolution for the InjectionConstructor in Unity. I'd go with ResolvedParameter:

    // At "Startup"
    container.RegisterType<IA, A>(
        new InjectionConstructor(
            new ResolvedParameter<AppEnv>("JustANameIfYouHaveMany")));
    
    container.RegisterType<IB, B>(
        new InjectionConstructor(
            new ResolvedParameter<AppEnv>("JustANameIfYouHaveMany")));
    
    // Whenever you can get the proper value of AppEnv
    AppEnv correctValue = AppEnv.WhateverLogic();
    container.RegisterInstance<AppEnv>("JustANameIfYouHaveMany", correctValue);
    

    With what I wrote, you can do the startup registration the earliest you can, but as long as you do the second part of the registrations before you container.Resolve<IA or IB>(), it's going resolve fine.