7

I'm using an ORM which doesn't allow me to inject dependencies in the constructor. Let's say I'm using DDD for the business logic, and the MVC pattern for the UI.

Now one of my domain objects needs to access an external service. I'm very opposed to the service locator anti-pattern (wouldn't touch it with a ten foot pole), but as I see it, that leaves me with the following:

class Controller
{
    private readonly IExternalService _externalService;

    public Controller(IExternalService externalService)
    {
        _externalService = externalService;
    }

    public ViewResult Action(Guid Id)
    {
        // Omitted repository access for brevity.
        domainObject.DoSomethingWichNeedsAnExternalService(_externalService);
    }
}

Somehow I get the feeling this isn't very clean, what if the "domainObject" is buried deep into the model/graph, should the "_externalService" be passed all the way down?

Are there any best-practice alternatives?

2

It seems like it will get out of hand. For instance, I had to use an IRealTimeClockService to inject into my units under test so that I could have repeatable test results for things that depend on the system time. That seems like a lot of weight for a service that just calls DateTime.Now. But I must admit that it really hasn't made the code less readable, even though you have to pass it to base class constructors too.

In some ways it's better because it's obvious what your dependencies are.

If you do have a lot of dependencies injected into an object, that might mean you're violating the single responsibility principle, and that class could be broken up into something that does two unrelated things.

On the other hand, if you have a complex system, you will have complex objects with lots of dependencies. I think it's better to be explicit about it.

Something to consider: if your class A takes 5 dependencies and passes 4 of them on to a helper object without touching them, perhaps you should just replace those 4 with a dependency on the helper object (or an interface, obviously).

  • I agree with your answer (I've even used a ITimeService myself). Though my problem is that I can't use constructor injection (let's assume I can't). I'm not sure how it's called, but I think I'm doing something like "Method injection" here. And I'm wondering if this is the way to go, since this way it could indeed be possible that class A takes a "dependency"/"service" as one of it's methods parameters, just to pass it along to another object's method etc... If there are best practises to deal with this, that would help too. – dvdvorle Sep 2 '11 at 23:29
  • @Mr Happy: there is a common alternative to constructor injection called Property Injection (I've mostly used it in MEF). Just as it sounds, the dependencies are injected into the properties rather than through the constructor. The down-side is that it's easier for a consumer to "forget" to set the dependencies, but in that case you just throw an exception. Basically, it's less explicit. – Scott Whitlock Sep 4 '11 at 13:54
1

What I've done is to create a factory class that creates all the other instances and wires them together. Then you don't have to pass dependent objects through constructors: Give the factory the replacement instances, and have it build everything else.

1

Wouldn't be wrapping the ORM api an option, so you can pass whatever you want to your wrapper's constructor?

Generally, when dealing with external apis, it might not be bad idea to do so. Plus, you are less tied to the ORM, which may be a nice in the future.

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.