Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
281 views
in Technique[技术] by (71.8m points)

c# - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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().


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...