【发布时间】:2011-12-05 18:55:00
【问题描述】:
简介
开始很简单:假设我有一个基本控制器,它使用数据访问对象(内部使用实体框架)来获取实体:
public class SomeController : Controller
{
private readonly DataAccess dataAccess;
public SomeController(DataAccess dataAccess)
{
this.dataAccess = dataAccess;
}
public ActionResult Index(int id)
{
var model = new Model();
model.Customer = this.dataAccess.Get(id);
return View(model);
}
}
问题
现在我想在我的数据访问类中执行一个异步任务,它可能运行 5 分钟,甚至更长。我不想重用注入的数据访问类,因为我喜欢为每个 HttpRequest 保留一个实体框架上下文。所以我想这样做:
public class SomeController : Controller
{
private readonly DataAccess dataAccess;
private readonly DataAccess dataAccessForAsyncTask;
public SomeController(DataAccess dataAccess, DataAccess dataAccessForAsyncTask)
{
this.dataAccess = dataAccess;
this.dataAccessForAsyncTask = dataAccessForAsyncTask;
}
public ActionResult Index(int id)
{
var model = new Model();
model.Customer = this.dataAccess.Get(id);
this.dataAccessForAsyncTask.ExecuteAsyncTask();
return View(model);
}
}
问题 2
我的数据访问类在 .InstancePerHttpRequest() 中注册,因为我喜欢为每个 HttpRequest 保留一个实体框架上下文。
问题
这甚至可能吗?还是我应该完全不同? 如果可能的话,我如何使用 Autofac 完成此任务?
更新
根据 Dennis Palmer 的回答,我调整了我的代码。我的解决方案是创建一个必须执行的服务的新实例,这次不使用 Autofac。 (因为必须异步执行的任务运行时间很短,所以我选择不使用队列。)
// This controller just calls a method on my Service Layer. Nothing special.
public class SomeController : Controller
{
private readonly Service service;
public SomeController(Service service)
{
this.service = service;
}
public ActionResult Index(int id)
{
var model = new Model();
model.Customer = this.service.Get(id);
return View(model);
}
}
// This is the Service where the magic happens.
Public class Service
{
private readonly DataAccess dataAccess;
// This constructor is used if we want to create a new
// instance without Autofac
public Service()
{
this.dataAccess = new DataAccess();
}
// This constructor is used if we want to let Autofac
// create a new instance
public Service(DataAccess dataAccess)
{
this.dataAccess = dataAccess;
}
public Customer Get(long id)
{
// Get the customer in a Synchronous way.
var customer = dataAccess.Get(id);
// Now we have to do something Async.
// Solution: create a new instance by hand, of the
// class that holds the method we want to call Async.
var serv = new Service();
// Execute the call in a async way.
new Action<long, long>(serv.DoSomething).BeginInvoke(null, null);
return customer;
}
// This is the method we want to execute async.
public void DoSomething()
{
// Do something short or long running.
}
}
【问题讨论】:
标签: c# asp.net-mvc dependency-injection inversion-of-control autofac