Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving type with PerRequestLifetimeManager without HTTP request

I have a MVC application that uses IoC with Unity and I have a DbContext implementation defined using the PerRequestLifetimeManager. This object is injected to controllers through Unit of Work implementation.

container.RegisterType<DBContext, MyContext>(new PerRequestLifetimeManager());

Everything is working fine so far and the app has a decent number of models and controllers. Now what I was trying to do recently is add some automated tasks for this application and for this purpose I wanted to use HangFire.

I've set up this library in my project and created a simple task in which I want to invoke an action that requires a DBContext.

RecurringJob.AddOrUpdate(() => MyTask(), Cron.Daily);

and MyTask() is defined as follows

public void MyTask()
{
    var taskManager = container.Resolve<ITaskManager>();
    taskManager.DoSomething();
}

Task manager requires an instance of DBContext (through Unit of Work object)

public class TaskManager : ITaskManager
{
    public TaskManager(IUnitOfWork uow) {
        ...
    }
}

public class UnitOfWork : IUnitOfWork
{
    public class UnitOfWork(DBContext context) {
        ...
    }
}

Now the problem I have is whenever the task runs I get the exception saying PerRequestLifetimeManager can only be used in the context of an HTTP request.

Is there a way I could inject this object without HTTP request or how can I change my Unity configuration to also support my HangFire tasks?

like image 313
RaYell Avatar asked Aug 31 '14 15:08

RaYell


1 Answers

I have moved away from using PerRequestLifetimeManager for this very issue. I have now started using HierarchicalLifetimeManager with container hierarchies instead and then you need to set up your app to create a new child container per intended scope (such as a request or a job) and dispose that child container when that scope is complete.

There are some libraries that hook into MVC and WebAPI to create a new child container per request. A quick search found this one for MVC: Unity.Mvc5 and the official Unity.AspNet.WebApi NuGet package includes a UnityHierarchicalDependencyResolver.

To get this to work with your task app, you will have to roll your own method to create a child container to control your scope, but that is pretty easy. Just call IUnityContainer childContainer = container.CreateChildContainer(), resolve your instances using the child container and do your work and then at the end of your scope call childContainer.Dispose().

like image 96
TylerOhlsen Avatar answered Nov 02 '22 00:11

TylerOhlsen