0

I use structuremap as IOC container. I have three classes A, B and C. A has B and C as constructor dependencies, and B has C as constructor dependency. I illustrate it in the following figure:

                    A
                  ↗  ↖
                 /     \
                B       C
               ↗
              /
             C

And C has a list of plug-ins. I need, that every intance of such a CPlugIn is a new instance.

How do I need to configure structure map?

What did I do already?

This is my minimal not working example:

internal class Program
{
    private static void Main(string[] args)
    {
        var container = new Container(
            config =>
            {
                config.For<IA>().Use<A>();
                config.For<IB>().Use<B>();
                config.For<IC>().Use<C>().AlwaysUnique();

                config.For<ICPlugIn>().Add<CPlugIn1>().AlwaysUnique();
                config.For<ICPlugIn>().AlwaysUnique().Add<CPlugIn2>();
                config.For<ICPlugIn>().AlwaysUnique().Add<CPlugIn3>().AlwaysUnique();
            });

        var a = container.GetInstance<IA>();
        Console.WriteLine(a.ToString());
        Console.WriteLine();

        Console.ReadLine();
    }
}

public interface IA
{
}

public class A : IA
{
    public A(IB b, IC c)
    {
        B = b;
        C = c;
    }

    public IB B { get; }

    public IC C { get; }

    public override string ToString()
    {
        var message = $"A: {GetHashCode()}";
        message += Environment.NewLine + B;
        message += Environment.NewLine + C;
        return message;
    }
}

public interface IB
{
}

public class B : IB
{
    public B(IC c)
    {
        C = c;
    }

    public IC C { get; }

    public override string ToString()
    {
        var message = $"B: {GetHashCode()}";
        message += Environment.NewLine + "  " + C;
        return message;
    }
}

public interface IC
{
}

public class C : IC
{
    public C(IList<ICPlugIn> plugIns)
    {
        PlugIns = plugIns;
    }

    public IList<ICPlugIn> PlugIns { get; }

    public override string ToString()
    {
        var message = $"C: {GetHashCode()}";
        message += Environment.NewLine + "  C.PlugIns:";
        PlugIns.ForEach(p => message += Environment.NewLine + ($"    {p} {p.GetHashCode()}"));
        return message;
    }
}

This is the output:

A: 16246551
B: 12001237
  C: 40902273
  C.PlugIns:
    TestingStructureMapsLifecycles.CPlugIn1 32576140
    TestingStructureMapsLifecycles.CPlugIn2 24749807
    TestingStructureMapsLifecycles.CPlugIn3 21421675
C: 58577354
  C.PlugIns:
    TestingStructureMapsLifecycles.CPlugIn1 32576140
    TestingStructureMapsLifecycles.CPlugIn2 24749807
    TestingStructureMapsLifecycles.CPlugIn3 21421675

As you can see: I have different instances of C, but the share the same instances of their plug ins.

Rico-E
  • 1,806
  • 2
  • 28
  • 47
  • 1
    problem is `IList` in constructor ... so in fact you got the same list every time and since list is created once elements are also created once ... you may try to use `config.For>().Use(c => c.GetAllInstances().ToList()).AlwaysUnique();` and then normal `config.For().Use().AlwaysUnique()` for all – Selvin Aug 06 '21 at 15:15
  • or just `config.Scan(scan => { scan.AssemblyContainingType(); scan.WithDefaultConventions().OnAddedPluginTypes(c => c.ContainerScoped()); scan.AddAllTypesOf(); });` without `config.For()...` at all [here are examples of both](https://dotnetfiddle.net/Hb9ZkO) – Selvin Aug 06 '21 at 15:32
  • @Selvin: You are right. I added `For>().AlwaysUnique();` to the container configuration and it worked. If you could post your comment as an answer, I could mark it as answer. – Rico-E Aug 09 '21 at 18:25

0 Answers0