Search code examples
c#xamarindependency-injectionautofac

Autofac resolve the same class instance with different parameters


I have a Xamarin.Forms application where I am using Autofac for DI.

SO what I want is quite simple but I am unable to do something which seems like a sinch to do.

So I have a class that has two constructors both of them have a single parameter and based on certain conditions I want to resolve either one. As an example, I have a class A and what I want is based on conditions B or C should be resolved.

Eg:

public class A
{

   public A(B bObject)
   {...}

   public A(C cObject)
   {...}
}

But I am unable to understand how to do this. I tried doing something like below:

Registration:

 builder.RegisterType<A>().
            UsingConstructor(typeof(C)).
            Named<A>(nameof(C));

 builder.RegisterType<A>().
            UsingConstructor(typeof(B)).
            Named<A>(nameof(B));

Resolving:

DiContainer.ResolveNamed<A>(nameof(B));
DiContainer.ResolveNamed<A>(nameof(C));

Note: I have already Registered B and C in the container as shown below:

builder.RegisterType<B>();
builder.RegisterType<C>()

I am a little new to AutoFac and I am not even sure if this is the correct way, I think it has something to do with me registering it twice I am not sure.

Any suggestion or help is strongly appreciated.


Solution

  • You can try to use an Autofac lambda registration for that and perform a registration using the following snippet (c parameter here is IComponentContext instance)

    var builder = new ContainerBuilder();
    builder.Register(
        (c, p) =>
        {
            var condition = p.Named<bool>("condition");
            return condition ? new A(c.Resolve<B>()) : new A(c.Resolve<C>());
        });
    builder.RegisterType<B>();
    builder.RegisterType<C>();
    

    Then resolve A by passing a parameter to lambda expression. You can use TypedParameter instead of named (constant values only) or ResolvedParameter (dynamic values)

    var a = container.Resolve<A>(new NamedParameter("condition", true));
    

    If you don't want to explicitly call Resolve, you can have a look at delegate factories (Func<T> for example)