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

时间:2014-08-31 15:31:03

标签: c# .net httprequest unity-container hangfire

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

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

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

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

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

MyTask()定义如下

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

任务管理器需要一个DBContext实例(通过工作单元对象)

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

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

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

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

1 个答案:

答案 0 :(得分:12)

对于这个问题,我已经不再使用PerRequestLifetimeManager了。我现在开始使用HierarchicalLifetimeManager而不是container hierarchies,然后你需要设置你的应用程序,以便为每个预期的范围(例如请求或作业)创建一个新的子容器,并在以后处置该子容器范围是完整的。

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

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