Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StructureMap not possible to use injected instance for setter injection

I am having a problem with injecting an instance into structuremap for my tests.

My objects graph looks like this

internal class ConfigurationManager : IConfigurationManager : IManager
{
   public ISomeManager SomeManager { get; set; }
}

internal class SomeManager : ISomeManager : IManager
{
   public IConfigurationManager  ConfigurationManager { get; set; }
}

1) first i create the container and add all found registries

_container = new Container(c => c.Scan(s =>
{
   s.TheCallingAssembly();
   s.LookForRegistries();
}));

one of these scanned assemblies contains the following registration

x.For<IConfigurationManager>().Singleton.Use<ConfigurationManager>();

2) then i want to inject a special mock object for this managers

_configurationManagerStub = MockRepository.GenerateStub<IConfigurationManager>();
_container.Inject(_configurationManagerStub);

3) Then the manager instances are created without setter injection configured (to avoid circular dependencies)

foreach (Type pluginType in AllManagers())
{
   managerInstances.Add(_container.GetInstance(pluginType));
}

4) at last I use the BuildUp method to set the Properties of type IManager.

_container.Configure(x => x.SetAllProperties(c =>
{
   // configure the property injection for all managers
   c.Matching(prop => typeof(IManager).IsAssignableFrom(prop.PropertyType));
}));

// push in dependencies -> EXCEPTION
managerInstances.ForEach(x => _container.BuildUp(x));

Unfortunatly in the last line of code i get the following exception.

StructureMap.StructureMapException : StructureMap Exception Code: 245 Error while trying to create an InstanceBuilder for IConfigurationManagerProxyd079980359cf491b821a3afb15be8a86, DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null ----> System.ArgumentException : Expression of type 'System.Object' cannot be used for parameter of type 'System.String' of method 'Castle.Core.Interceptor.IInterceptor[] GetIInterceptor[]'

Why does structuremap try to use an InstanceBuilder when I did inject the instance?

Br, David

like image 599
David Leonhartsberger Avatar asked Jan 30 '11 12:01

David Leonhartsberger


1 Answers

The issue is with StructureMap support of Castle DynamicProxy (Rhino Mocks and Moq uses it) generated stubs when used in BuildUp.

Specifically Castle generates a constructor with 2 parameters for requested proxy type and those parameters don't have names. ConstructorFunctionBuilder within StructureMap fails to create proper lambda expression in such case (null is treated as System.Object where System.String is expected). Thats not even needed when you just want to setup property setters, but there is no way to control this.

The "Inject" will work with non-dynamically generated stubs, but you might wanna look for a different solution.

like image 138
Anton Avatar answered Sep 20 '22 11:09

Anton