2

Today at work a collegue and I had a discussion about the following:

Basically we have a rule engine which works in the following way:

RuleExecutor

  • Gets all rules to execute in the constructor like public RuleExecutor(ICollection<IRule> rulesToExecute) { ... }

  • Executes all rules by calling rule.ApplyRule(); for each rulesToExecute

Rules

  • Provide method ApplyRule(); which executes the rule

Now we want the RuleExecutor to be executed in a cron job.

We had a discussion about how to retrieve an instance of the RuleExecutor.

I think the "correct way" is via constructor injection

public RuleCronJob(IRuleExecutor ruleExecutor) { ... }

My collegue wants to use a "IocFactory" which has a static method GetInstance<>. So in the "execute method" of the cron job he would do something like var ruleExecutor = IocFactory.GetInstance<IRuleExecutor>();

public static TType GetInstance<TType>(params Tuple<string, object>[] constructorParameters)
    {
        if (constructorParameters.Any())
        {
            var constructorArgs = new Collection<ConstructorArgument>();
            foreach (var parameter in constructorParameters)
            {
                constructorArgs.Add(new ConstructorArgument(parameter.Item1, parameter.Item2, true));
            }

            return Kernel.Value.Get<TType>(constructorArgs.Cast<IParameter>().ToArray());
        }

        return Kernel.Value.Get<TType>();
    }

Kernel is a StandardKernel of Ninject.

I think the constructor injection is better because it allows for easier tests (mocking) etc. but I couln't convince him to use it because he thinks that the IocFactory "works as well so why not use it"...

  • What would be some arguments to convince him to use constructor injection instead of the IocFactory?
  • 4
    What your collegue wants to use is actually called a "service locator". Reams have been written about service locator vs. dependency injection, so searching google or this site is your best bet. – Ben Aaronson Jun 17 '15 at 12:45
5

Well, for a start, the IOCFactory, or rather the way you described it being used, is a bold-faced lie, because it involves no inversion of control. If you continue calling getInstance() yourself, you should a least rename the alleged IOCFactory.

As Ben Aaronson pointed out, a container without inversion of control is just a Service Locator. A lot has been written about Dependency Injection vs. Service Locators, over ten years ago by Martin Fowler on his blog, or five years ago on stackoverflow: https://stackoverflow.com/questions/1557781/whats-the-difference-between-the-dependency-injection-and-service-locator-patte

1

but I couln't convince him to use it because he thinks that the IocFactory "works as well so why not use it"...

Because it's more complicated?

Rather by definition, code that is doing more things has more things that can go wrong. For IoC containers, that often means lots of things going on under the covers to discover the various dependencies, resolve them, inject them... IoC containers are the nuclear option for dependency injection. They'll solve your problem, but are almost always overkill, and will leave nasty lingering effects around regardless.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.