StructureMap Specifying Explicit Constructor Arguments
Asked Answered
W

1

6

I'm working on legacy code.

I have different methods of the same class that pass different arguments to the constructor of a dependency. I'm trying to get some basic IoC usage introduced. Right now I have StructureMap passing my arguments like this:

var thing = ObjectFactory.GetInstance<IThingInterface>(new ExplicitArguments(
      new Dictionary<string, object> { 
          { "constructorArgA", notShown  }, 
          { "constructorArgB", redacted.Property } }));

Where the actual properties passed for constructorArgA and B change depending on where I am.

Instead of "constructorArgA" is there a way to configure this via actual types, like you can do when configuring the objectFactory, like:

x.For<IHidden>().Use<RealType>()
   .Ctor<IConfig>().Is(new Func<IContext, IConfig>(
        (context) => someMethodToGetIConfig()));

If I were writing this from scratch I'd probably structure the dependencies a bit different to avoid this, but that's not an option for me right now.

Widener answered 15/8, 2011 at 21:22 Comment(1)
OR should I switch to property injection instead of constructor injection?Widener
D
3

This is something of a classic/common question with DI Containers.

My first choice would be to create a "manual" abstract factory to create IThingInterface, and then use Structuremap to inject IThingInterfaceFactory where it is needed. By manual factory, I mean a class the calls new ThingInterface() and returns it. If you do it this way, your implementation will no longer be container-managed, and if it has dependencies, they would no longer be provided by the container (may or may not be a problem for you).

Second choice would be to create an abstract factory that actually uses/wraps the container. So basically your first code snippet but wrapped in a factory class where the Create() method takes your parameters. This has the advantage of everything (including your implementation and its dependencies) being container-managed, but the disadvantage of referencing your container directly (which is not a best practice--see Article on Composition Roots).

You could also do setter injection, but I would personally consider it a last resort.

Castle Windsor has a good solution to this problem built in (Typed Factory Facility). Not sure if switching containers in an option, but you might consider it.

Dace answered 15/8, 2011 at 21:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.