Structuremap uses a static property insertion configuration for each new container instance

I am working on an outdated application, and my current goal is to establish some kind of integration test, which also uses a structure map. So far, I have not had problems using SM for unit testing and production code for almost a year. But, unfortunately, we are forced to use setter injection, because our BOs are a real dependent beast (many of these objects have circular dependencies on others)

Our training for this was to use a two-stage approach: whether we first created all these objects without input properties (which cause these circular dependencies), and after the chambers create these objects (introduce dependency objects through their properties), when they were already created. (See Examples of Class A, B, and Logic that have circular dependencies)

This has worked so far β†’ When we run, suppose that three integration tests after each other than the first one β€œturns green”, the other test throws execptions when the structmap tries to create instances (in the GetManagerInstances methods).

I assume that SM saves its config file.

Definitions

internal interface IM { } internal interface ILogic { } internal interface IMA : IM { } internal interface IMB : IM { } internal class A : IMA { public A() { Console.WriteLine("A"); } public IMB BInstance { get; set; } } internal class B : IMB { public B() { Console.WriteLine("B"); } public IMA AInstance { get; set; } public ILogic Logic { get; set; } } internal class Logic : ILogic { public Logic() { Console.WriteLine("Logic"); } public IMA AInstance { get; set; } } 

Initialization

 private static IContainer _container; while (true) { Initialize(); } internal static void Initialize() { _container = new Container(c => { c.For<ILogic>().Singleton().Use<Logic>(); c.For<IMB>().Singleton().Use<B>(); c.For<IMA>().Singleton().Use<A>(); }); // All managers are created and afterwards properties are set to avoid a circular build stack. List<object> managerInstances = GetManagerInstances(); // After the manager instances are created the dependencies are injected in the properties. BuildUpManagersUsingPropertyInjection(managerInstances); } private static List<object> GetManagerInstances() { List<object> managerInstances = new List<object>(); foreach (Type pluginType in new List<Type> { typeof(IMA), typeof(IMB) }) { try { managerInstances.Add(_container.GetInstance(pluginType)); } catch (Exception ex) { // exception on second test run -> see below } } return managerInstances; } private static void BuildUpManagersUsingPropertyInjection(List<object> managerInstances) { _container.Configure(x => x.SetAllProperties(c => { // configure the property injection for all managers c.Matching(prop => typeof(IM).IsAssignableFrom(prop.PropertyType)); // client logic is also used by managers c.TypeMatches(type => type.Equals(typeof(ILogic))); })); _container.BuildUp(_container.GetInstance<ILogic>()); managerInstances.ForEach(x => _container.BuildUp(x)); } 

Result

StructureMap exception code: 295 A bi-directional dependency problem was detected using RequestedType: StructureMapTests.IMA, Name: 237b6fb1-7dee-4f09-b663-c33bb793afc6, ConcreteType: StructureMapTests.A. BuildStack: 1.) RequestedType: StructureMapTests.IMA, Name: 237b6fb1-7dee-4f09-b663-c33bb793afc6, ConcreteType: StructureMapTests.A 2.) RequestedType: StructureMapTests.IMB, Name: ad692281-cd27fdccdc4cdcdc : StructureMapTests.B Exception on creation *

Analysis

Output for the first test run:

B
Logic β†’ Everything is OK

Output for the second test run:
B
Instance Exception
B

Exception in the construction of Logic

B β†’ ERROR REPORT

Please, help: (

EDIT I am targeting the 4.0.Net framework and using StructureMap release 2.6.2

+4
source share
2 answers

I confirmed that this is a bug in the current version of StructureMap (as of January 2011). Setter injection policies are actually not correctly distributed between containers. The message was sent to the StructureMap mailing list .

+4
source

this solves the cyclical dependency problem (an exception is not thrown during initialization), but the properties are not populated correctly.

A.BInstance = null
B.AInstance = null
Logic.AInstance = null

properties must be set to the correct instance!

0
source

Source: https://habr.com/ru/post/1337441/


All Articles