Arithmomaniac
Arithmomaniac

Reputation: 4804

Custom resolve nested dependencies

Suppose the following class structure:

ClassA (IClassB classb, IClassC classc) : IClassA
ClassB (IClassC classc) : IClassB
ClassC1 () : IClassC
ClassC2 () : IClassC

Suppose I want to use ClassC1 whenever it is used to resolve specifically IClassA, i.e. container.GetInstance<IClassA>() would return

new ClassA(
 new ClassB (new ClassC1()),
 new ClassC1()
)

Can I do something like this in StructureMap? (Ideally, something like For<ClassA>().Nest(x => x.For<IClassC>().Use<ClassC1>()), but anything would do.)

Upvotes: 1

Views: 134

Answers (1)

Kirill
Kirill

Reputation: 3454

This is what I got:

public interface IClassA
{
}

public interface IClassB
{
}

public interface IClassC
{
}

public class ClassA: IClassA
{
    public ClassA(IClassB classb, IClassC classc)
    {
        Console.WriteLine("ClassA");
        Console.WriteLine("  ClassB: {0}", classb.GetType());
        Console.WriteLine("  ClassC: {0}", classc.GetType());
    }
}

public class ClassB : IClassB
{
    public ClassB(IClassC classc)
    {
        Console.WriteLine("ClassB");
        Console.WriteLine("  ClassC: {0}", classc.GetType());
    }
}

public class ClassC1 : IClassC
{
    public ClassC1()
    {
        Console.WriteLine("ClassC1");
    }
}

public class ClassC2 : IClassC
{
    public ClassC2()
    {
        Console.WriteLine("ClassC2");
    }
}

class Program
{
    static void Main(string[] args)
    {
        IContainer container = ConfigureDependencies();

        container.GetInstance<IClassA>();
        container.GetInstance<IClassB>();
    }

    private static IContainer ConfigureDependencies()
    {
        return new Container(x =>
        {
            x.For<IClassA>().Use<ClassA>();
            x.For<IClassB>().Use<ClassB>();
            x.For<IClassC>().Use(z => z.RootType == typeof(ClassA) ? (IClassC) z.GetInstance<ClassC1>() : z.GetInstance<ClassC2>());
        });
    }

}

Concrete type of IClassC is determined by RootType.

This is output:

ClassC1
ClassB
  ClassC: MongodbEnumerable.ClassC1
ClassA
  ClassB: MongodbEnumerable.ClassB
  ClassC: MongodbEnumerable.ClassC1
ClassC2
ClassB
  ClassC: MongodbEnumerable.ClassC2

It shows that ClassC1 was used for constructing ClassA and its dependencies but for constructing separate IClassB was used ClassC2.

Upvotes: 1

Related Questions