具有外部应用程序的 Autofac 生存期范围

本文关键字:Autofac 生存期 范围 应用程序 外部 | 更新日期: 2023-09-27 18:35:49

可能需要

更多问题才能很好地理解这个主题。我已经阅读了很多文档,但我无法完全弄清楚。

例如:

单例 1 = 在生命周期内解析范围 1

Singleton1 处理来自 Tcp/IP 的消息。DataService 处理来自 Web 控制器的消息,并处理来自 Singleton1 的消息(意思是来自 Tcp/IP 的消息)。

在DataService中,有一个组件注册为PerLifetimeScope(DbContext)。

我无法理解的是:

  1. 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();
}

具有外部应用程序的 Autofac 生存期范围

这是 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);
        }
    }
}

正如文章将解释的那样,您现在正在酿造一批不错的"范围汤"。

请密切注意嵌套生存期范围和范围共享。您对单例的使用可能会让您感到困惑。