Question

Can't get my head around the parameter passing in Autofac, the following code doesn't work:

class Config {
    public Config(IDictionary<string, string> conf) {}
}

class Consumer {
    public Consumer(Config config) {}
}

void Main()
{
    var builder = new Autofac.Builder.ContainerBuilder();
    builder.Register<Config>();
    builder.Register<Consumer>();
    using(var container = builder.Build()){
        IDictionary<string,string> parameters = new Dictionary<string,string>();
        var consumer = container.Resolve<Consumer>(Autofac.TypedParameter.From(parameters));
    }
}

that throws:

DependencyResolutionException: The component 'UserQuery+Config' has no resolvable constructors. Unsuitable constructors included:
Void .ctor(System.Collections.Generic.IDictionary`2[System.String,System.String]): parameter 'conf' of type 'System.Collections.Generic.IDictionary`2[System.String,System.String]' is not resolvable.

but the following code does work:

IDictionary<string,string> parameters = new Dictionary<string,string>();
var config = container.Resolve<Config>(Autofac.TypedParameter.From(parameters));
var consumer = container.Resolve<Consumer>(Autofac.TypedParameter.From(config));
Was it helpful?

Solution

Repeating here the answer from the Autofac mailing list:

The parameters passed to Resolve only related to the direct implementer of the service you're resolving, so passing Config's parameters to the resolve call for Consumer won't work. The way around this is to change your Consumer registration to:

builder.Register((c, p) => new Consumer(c.Resolve<Config>(p))); 

OTHER TIPS

Autofac is obviously trying to resolve the parameter of your Config class in the assumption that the Dictionary itself is a resolvable type. I do not know the autofac syntax on how to do it. But you probably need to do more steps when registring the Config type, e. g. giving it a delegate that passes in a new Dictionary.

Unfortunately, IoC containers like Autofac doesn't come equipped with a "please read my mind module".

What you're trying to do is basically saying "I know one of the types involved here needs a dictionary, and I need a service of type Consumer, can you please try to figure out what it is that I'm taking about and just do the right thing?".

If you resolve one service, and specify a parameter, that parameter will be attempted to be used for that particular service. The container will not try to propagate that parameter value down to any dependencies.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top