Using Dependency Injection outside of a Controller's constructor

One possible solution is to make the OrderParser class non-static and inject an instance of it in the constructor of the Controller that triggers the action (DoWork).

Then make OrderParser's constructor take an IOrderRepository parameter and the IoC container will gladly take care of it.

Also, beware of things like:

DependencyResolver.Current.GetService<ISomeInterface>();

This is called Service Locator and it's considered to be an anti-pattern. Avoid it if possible.

Basically, the only place where you should reference DependencyResolver.Current.GetService is your implementation of IControllerFactory that enables DI in the first place.

Update:

It would be best if you did this in another application than your MVC website. Two alternatives would be:

  • a Windows Service that performs that action based on a timer
  • a Console application that is run using Windows Task Scheduler every hour

These, being separate applications would have their own Composition roots that would deal with the object instantiation / dependency injection issue.

If, however, you are constrained to do this from your web app (for example - you have a hosting that only allows web apps), then you may find it acceptable to make an exception to the "Don't use the Dependencey Resolver directly" rule and do somehing like this on the application startup:

var runner = DependencyResolver.Current.GetService<OrderParsingRunner>();
runner.StartWorking();

Of course, the OrderParsingRunner class would look something like this:

public class OrderParsingRunner
{
    private readonly OrderParser orderParser;

    public OrderParsingRunner(OrderParser orderParser)
    {
        this.orderParser = orderParser;
    }

    public StartWorking()
    {
        TaskFactory.StartNew(() => 
            { 
                DoWorkHourly();
            });
    }

    private DoWorkHourly()
    {
        while(true)
        {
            Thread.Sleep(TimeSpan.FromHours(1));

            orderParser.DoWork();
        }
    }
}

Disclaimer: I haven't actually compiled/run this code, I just wrote it to illustrate the concept.

Please note that this is a workaround rather than an actual solution. It's recommended that you use another application for the background tasks if possible.


You shouldn't need static helper classes when using DI. You can treat everything as a "service" and declare your dependencies in your constructor. That's how I think about it. Then everything just gets created for you as you need it.

So I would change your static class to a non-static and inject it where needed via the constructor.

Answer for Edit 2

Pass your container in to the bootstrap class.

class bootstrapper
{
    Initialize(DependencyResolver container)
    {
        var parser = new OrderParser(container.Resolve<IOrderRepository>());
        parser.DoWork();
    }
}

Edit

I would actually do this ...

var parser = container.Resolve<OrderParser>();

and let the dependency resolver figure everything out!