具有外部应用程序的 Autofac 生存期范围
本文关键字:Autofac 生存期 范围 应用程序 外部 | 更新日期: 2023-09-27 18:35:49
可能需要
更多问题才能很好地理解这个主题。我已经阅读了很多文档,但我无法完全弄清楚。
例如:
单例 1 = 在生命周期内解析范围 1
Singleton1 处理来自 Tcp/IP 的消息。DataService 处理来自 Web 控制器的消息,并处理来自 Singleton1 的消息(意思是来自 Tcp/IP 的消息)。
在DataService中,有一个组件注册为PerLifetimeScope(DbContext)。
我无法理解的是:
- DataService 如何知道它当前是否处理 Http 请求(并且应该使用 DbContext 的实例 1)或 Tcp/Ip(并使用 DbContext 的实例 2)?
我的最终目标是配置 Autofac,以便为我收到的每个 Tcp/Ip 请求创建一个新的生存期范围。就像它自动处理 Http 请求一样!
注意:
如果代码更容易理解,我会说,我只是认为这可能会使事情复杂化。
如果我说的任何话是愚蠢或不正确的,请修复我。很难学会这个。
谢谢!
编辑:
添加代码以更好地解释我的问题:
public class Singleton1 : ISingleton1
{
private IDataService _dataService;
public Singleton1(IDataService dataService)
{
_dataService = dataService;
}
public void HandleExternalAddItemMessage(AddItemMessage msg)
{
_dataService.AddItem(msg.Item);
}
}
public interface IUnitOfWork : IDisposable
{
void Commit();
}
public EFUnitOfWork : IUnitOfWork
{
private DbContext _context;
public EFUnitOfWork(DbContext context)
{
_context = context;
}
public void Commit()
{
_context.SaveChanges();
}
}
public class DataService
{
private Func<Owned<IUnitOfWork>> _unitOfWorkFactory;
public (Func<Owned<IUnitOfWork>> unitOfWorkFactory)
{
_unitOfWorkFactory = unitOfWorkFactory;
}
// This method is called from both controllers and external Tcp/Ip calls. How do I do it - how do I set the context that is in the unit of work???
public void AddItem(Item item)
{
using(unitOfWork = _unitOfWorkFactory())
{
...
}
}
}
Startup code:
{
_container.RegisterType<IDataService, DataService>().SingleInstance();
_container.RegisterType<Singleton1, ISingleton1>().SingleInstance();
_container.RegisterType<EFUnitOfWork, IUnitOfWork>().PerDepnendecny();
_container.RegisterType<DbContext, MyDbContext>().InstancePerLifetimeScope();
}
这是 Nicholas Blumhardt 的一篇很棒的文章,涉及围绕对象生存期的许多问题,包括试图在 Autofac 中拥有对象处置的开发人员的常见陷阱。
http://nblumhardt.com/2011/01/an-autofac-lifetime-primer/
我认为您尝试做的事情可能过于复杂,并且模型可能可以简化,但是可以通过手动创建自己的LifetimeScope
来注册对象的新实例。
public class Singleton1 : ISingleton1
{
private readonly ILifetimeScope _lifetimeScope;
public Singleton1(ILifetimeScope lifetimeScope)
{
_lifetimeScope = lifetimeScope;
}
public void HandleExternalAddItemMessage(AddItemMessage msg)
{
using(var scope = _lifetimeScope.BeginLifetimeScope())
{
var dataService = scope.Resolve<IDataService>();
dataService.AddItem(msg.Item);
}
}
}
正如文章将解释的那样,您现在正在酿造一批不错的"范围汤"。
请密切注意嵌套生存期范围和范围共享。您对单例的使用可能会让您感到困惑。