具有外部应用程序的Autofac Lifetime范围

时间:2016-02-22 11:32:58

标签: c# dependency-injection autofac ioc-container unit-of-work

它可能需要更多的问题才能很好地理解这个主题。 我已经阅读了很多文档,但我无法完全弄明白。

比如说:

Singleton1 =已解决 lifetimeScope1

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

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

我无法理解的是:

  1. DataService如何知道它当前是否处理Http请求(并且应该使用DbContext的实例1)或Tcp / Ip(并使用DbContext的实例2)?
  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();
    
    }
    

1 个答案:

答案 0 :(得分:0)

尼古拉斯·布鲁姆哈特(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);
        }
    }
}

正如文章将解释你现在正在酝酿一批很好的汤#&#34;。

密切关注嵌套生命周期范围范围共享。你对单身人士的使用可能会让你失望。