在ASP.NET中使用Autofac与ContainerDisposalModule一起,我怎么能支持消防和忘记,有一个需要解决的问题组件的依赖电话? 我遇到的问题是,ASP.NET请求完成并配置面前的任务是跑的请求的生命周期范围,所以需要在新线程得到解决任何部件出现故障消息“实例不能得到解决和嵌套寿命不能因为它已经被置于”这个LifetimeScope被创建。 什么是支持消防和忘记在ASP.NET中使用Autofac呼叫的最佳方法是什么? 我不想耽误执行它可以在后台线程来完成某些任务的要求。
Answer 1:
您需要创建一个新的寿命范围是独立请求寿命范围。 下面的博客文章显示了如何做到这一点使用MVC但相同的概念可以适用于WebForms的一个例子。
http://aboutcode.net/2010/11/01/start-background-tasks-from-mvc-actions-using-autofac.html
如果您需要确保请求完成后异步工作肯定是执行,那么这是不是一个好方法。 在这种情况下我建议请求允许一个单独的进程把它捡起并执行工作期间将消息写入到队列中。
Answer 2:
答张贴由Alex适应当前Autofac和MVC版本:
- 使用
InstancePerRequest
的数据库上下文 - 添加
ILifetimeScope
的依赖才能到容器 -
SingleInstance
确保它的根寿命范围 - 使用
HostingEnvironment.QueueBackgroundWorkItem
在后台运行可靠的东西 - 使用
MatchingScopeLifetimeTags.RequestLifetimeScopeTag
避免不必知道的标记名autofac用来PerRequest寿命
https://groups.google.com/forum/#!topic/autofac/gJYDDls981A https://groups.google.com/forum/#!topic/autofac/yGQWjVbPYGM
要点: https://gist.github.com/janv8000/35e6250c8efc00288d21
的Global.asax.cs:
protected void Application_Start() {
//Other registrations
builder.RegisterType<ListingService>();
builder.RegisterType<WebsiteContext>().As<IWebsiteContext>().InstancePerRequest(); //WebsiteContext is a EF DbContext
builder.RegisterType<AsyncRunner>().As<IAsyncRunner>().SingleInstance();
}
AsyncRunner.cs
public interface IAsyncRunner
{
void Run<T>(Action<T> action);
}
public class AsyncRunner : IAsyncRunner
{
public ILifetimeScope LifetimeScope { get; set; }
public AsyncRunner(ILifetimeScope lifetimeScope)
{
Guard.NotNull(() => lifetimeScope, lifetimeScope);
LifetimeScope = lifetimeScope;
}
public void Run<T>(Action<T> action)
{
HostingEnvironment.QueueBackgroundWorkItem(ct =>
{
// Create a nested container which will use the same dependency
// registrations as set for HTTP request scopes.
using (var container = LifetimeScope.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag))
{
var service = container.Resolve<T>();
action(service);
}
});
}
}
调节器
public Controller(IAsyncRunner asyncRunner)
{
Guard.NotNull(() => asyncRunner, asyncRunner);
AsyncRunner = asyncRunner;
}
public ActionResult Index()
{
//Snip
AsyncRunner.Run<ListingService>(listingService => listingService.RenderListing(listingGenerationArguments, Thread.CurrentThread.CurrentCulture));
//Snip
}
ListingService
public class ListingService : IListingService
{
public ListingService(IWebsiteContext context)
{
Guard.NotNull(() => context, context);
Context = context;
}
}
文章来源: Resolving Autofac components in background Tasks in ASP.NET