Andy Andy - 1 month ago 14
C# Question

Circular dependencies in StructureMap - can they be broken with property injection?

I've got the simplest kind of circular dependency in structuremap - class A relies on class B in its constructor, and class B relies on class A in its constructor. To break the dependency, I made class B take class A as a property, rather than a constructor argument, but structuremap still complains.

I've seen circular dependencies broken using this method in other DI frameworks - is this a problem with Structuremap or am I doing something wrong?

Edit:
I should mention that class B's property is an array of class A instances, wired up like this:

x.For<IB>().Singleton().Use<B>().Setter(y => y.ArrayOfA).IsTheDefault();


Just to clarify, I want the following sequence of events to occur:


  • Construct an instance of B, "b"

  • Construct an instance of A, "a", injecting "b" into its constructor

  • Set "b.ArrayOfA" to ["a"]



And I want all this to happen using autowiring, if possible...

Edit 2: Here's a simplified example that uses explicit wiring up:

interface ILoader { }
interface ILoaderManager { }

class Loader : ILoader
{
public Loader(ILoaderManager lm) { }
}
class LoaderManager : ILoaderManager
{
public ILoader Loader { get; set; } // Was an array, but same circular dependency appears here
}

ObjectFactory.Configure
(
x =>
{
x.For<ILoader>.Singleton().Use<Loader>();
x.For<ILoaderManager>().Singleton().Use<LoaderManager>().OnCreation((c, a) => a.Loader = c.GetInstance<ILoader>());
}
);


Validating the configuration causes "Bidirectional Dependency Problem detected with RequestedType: IocTest2.ILoader..."

Answer

The closest you can get is something like this:

x.For<IB>().Use<B>()
    .OnCreation((ctx, instance) =>
    {
        instance.ArrayOfA = new IA[] {new A(instance) };
    });

If A has other dependencies that you want to resolve from the container, you can retrieve them from ctx within the OnCreation lambda.