1

Say I've the following class definition:

public class CreateThingyController : ICreateThingyController
{
    private readonly ICreateThingyHandler handler;

    private ISomeBusinessRuleBehaviourDependingOnFlag rule;

    public CreateThingyController(ICreateThingyHandler handler)
    {
        handler = handler;
    }

    public void CreateThingy(string something, bool flag)
    {
         if(flag) rule = new BlaImplementation()
         else rule = new BoehImplementation 
    }
}

I really dislike setting the behaviour at runtime like this, so I'd like to leverage SimpleInjector for this. But since I only know what to pick at runtime, depending on some variable I have no idea how to approach this..

Any help would be greatly appreciated!

Edit: Oh, wow, I'm just now beginning the benefit of using a DI container. Awesome stuff.

Learner
  • 97
  • 10
  • 1
    Factory pattern – FCin Mar 09 '18 at 10:21
  • See [Dependency injection type-selection](https://stackoverflow.com/a/34331154), [Dependency Injection Unity - Conditional Resolving](https://stackoverflow.com/a/32415954), and [Factory method with DI and IoC](https://stackoverflow.com/a/31971691). – NightOwl888 Mar 09 '18 at 11:15
  • 1
    @Learner you already commented that you know about RegisterConditional. Did you try it? Did you check the members of PredicateContext? You can't use unknown fields and varialbes in the expression when the controller isn't even created yet. You *could* use the consumer type but this defeats the purpose of DI. You could inspect the type for specific attrributes. – Panagiotis Kanavos Mar 09 '18 at 12:48
  • 1
    BTW what *is* the condition you want to use? It can't be `CreateThingy`, this has nothing to do with *dependency* injection, that method executes a decision righ there in the code. If you want to abstract creation until runtime, you should use the *Factory* pattern whether you use DI or not – Panagiotis Kanavos Mar 09 '18 at 12:51
  • Thank you, very valuable advice! – Learner Mar 09 '18 at 15:21

1 Answers1

2

You might want to look into the Factory pattern here.

public class BusinessRuleBehaviourFactory : ISomefactory
{
    public ISomeBusinessRuleBehaviourDependingOnFlag Create(string flag)
    {
        if (flag == "something")
            return new BlaImplementation();
        else if (flag == "something else")
            return new BoehImplementation();

        return new DefaultImplementation();
    }
}

Then you just inject your factory into your class

public CreateThingyController(ICreateThingyHandler handler, ISomeFactory someFactory)
{
    handler = handler;
    factory = someFactory;
}
KingChezzy
  • 136
  • 7
  • Yeah, this is basically what I had, but I don't find it an elegant solution, as it basically just relays a SelectImplementation() method to more code. So I'm looking for some SimpleInjector ninjary, to have it take care of this – Learner Mar 09 '18 at 10:51
  • 2
    @Learner How do you imagine it will know which implementation to take? You have to provide it some kind of parameter. Factory pattern is commonly used, elegant solution which keeps instatiation inside a single method DRYing your code. – FCin Mar 09 '18 at 10:55
  • 'How do you imagine it will know which implementation to take? ' That's what I like to figure out :) I know there is support for RegisterConditional in SimpleInjector, but I don't understand how to leverage it in this case – Learner Mar 09 '18 at 11:04
  • 1
    @Learner did you *check* its documentation? Is the information you want in the [PredicateContext](https://simpleinjector.org/ReferenceLibrary/html/T_SimpleInjector_PredicateContext.htm) class? BTW you *can't* use an unknown variable with an unknown value to specify the condition. The condition will execute *before* the controller is even created. – Panagiotis Kanavos Mar 09 '18 at 12:45
  • 1
    @Learner and anyway, what you ask is unrelated to DI. DI is about *dependency* injection. What you ask is creating different objects based on knowledge known only at runtime. That's the very description of the Factory pattern. – Panagiotis Kanavos Mar 09 '18 at 12:52
  • All right, thanks for the advice. I will look in to this then :) – Learner Mar 09 '18 at 14:50