使用不带HTTP请求的PerRequestLifetimeManager解析类型

RaY*_*ell 5 .net c# unity-container httprequest hangfire

我有一个使用IoC与Unity的MVC应用程序,我有一个DbContext使用PerRequestLifetimeManager.该对象通过工作单元实现注入控制器.

container.RegisterType<DBContext, MyContext>(new PerRequestLifetimeManager());
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都运行良好,应用程序有相当数量的模型和控制器.现在我最近要做的是为这个应用程序添加一些自动化任务,为此我想使用HangFire.

我在我的项目中设置了这个库并创建了一个简单的任务,我想在其中调用一个需要的动作DBContext.

RecurringJob.AddOrUpdate(() => MyTask(), Cron.Daily);
Run Code Online (Sandbox Code Playgroud)

MyTask()定义如下

public void MyTask()
{
    var taskManager = container.Resolve<ITaskManager>();
    taskManager.DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

任务管理器需要一个DBContext实例(通过Unit of Work对象)

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

public class UnitOfWork : IUnitOfWork
{
    public class UnitOfWork(DBContext context) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我遇到的问题是每当任务运行时我都会得到异常说法PerRequestLifetimeManager can only be used in the context of an HTTP request.

有没有办法可以在没有HTTP请求的情况下注入此对象,或者如何更改Unity配置以支持我的HangFire任务?

Tyl*_*sen 13

我已经不再使用PerRequestLifetimeManager这个问题了.我现在已经开始使用HierarchicalLifetimeManager容器层次结构来代替,那么你需要设置你的应用程序时,该范围内完成创建每预期的范围一个新的子容器(如请求或工作),并处理该子容器.

有一些库挂钩到MVC和WebAPI,以便为每个请求创建一个新的子容器.快速搜索发现这个用于MVC:Unity.Mvc5和官方Unity.AspNet.WebApi NuGet包中包含一个UnityHierarchicalDependencyResolver.

要使其与您的任务应用程序一起使用,您必须使用自己的方法来创建子容器来控制范围,但这非常简单.只需调用IUnityContainer childContainer = container.CreateChildContainer(),使用子容器解析您的实例并完成您的工作,然后在范围调用结束时childContainer.Dispose().