gpt4 book ai didi

c# - 注入(inject)两个对象实例

转载 作者:行者123 更新时间:2023-11-30 22:33:16 25 4
gpt4 key购买 nike

简介

开始很简单:假设我有一个基本 Controller ,它使用数据访问对象(在它内部使用 Entity Framework )来获取实体:

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 分钟,甚至更长。我不想重用注入(inject)的数据访问类,因为我喜欢为每个 HttpRequest 保留一个 Entity Framework 上下文。所以我想这样做:

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 保留一个 Entity Framework 上下文。

问题

这可能吗?或者我应该完全不同地做这件事吗?如果可能的话,我如何使用 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.
}
}

最佳答案

我认为您不需要单独的 dataAccess 实例。即使您的请求立即返回,执行异步代码的线程也需要保持事件状态,直到该代码执行完毕。因此,您的每个请求一个上下文应该可以正常工作。

View 将立即返回给客户端,但处理该请求的线程应继续运行,直到异步任务完成。如果没有发生这种情况,那么您应该问一个问题,了解如何使该线程保持足够长的时间以使其发生,并且对线程和异步操作了解更多的人可以提供更好的答案。

编辑:(回应评论)因此,如果数据上下文正在处理,那么您就会遇到线程问题。无论您如何实例化或注入(inject)数据上下文对象,如果线程的生命周期不足以让异步任务完成运行,它们就会被中断。

如果它是一个长时间运行的后台任务,我会考虑使用消息队列并实现一个后台任务,该任务在独立于您的 MVC 应用程序的自己的进程上运行。类似于 Windows Azure 中的辅助角色。

关于c# - 注入(inject)两个对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8390341/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com