Asp.net web api web应用程序中的Autofac PerLifetimeScope与PerRequest

Asp.net web api web应用程序中的Autofac PerLifetimeScope与PerRequest,asp.net-web-api,dependency-injection,autofac,communication,unit-of-work,Asp.net Web Api,Dependency Injection,Autofac,Communication,Unit Of Work,使用Autofac DI容器- 根据请求在web应用程序中注册工作单元与将其注册为PerLifetimeScope有什么区别 Autofac为每个请求创建一个新的作用域,通过将工作单元注册为PerMatchingScope,它将从为请求创建的作用域中得到解决 如果我错了,请纠正我,否则,有什么区别 此外,如果我将UoW注册为PerLifetimeScope,并且有一个控制台应用程序通过Tcp/Ip向我的web服务器发送需要创建该UoW的Mesages,那么将如何处理它 谢谢 编辑: public

使用Autofac DI容器-

根据请求在web应用程序中注册工作单元与将其注册为PerLifetimeScope有什么区别

Autofac为每个请求创建一个新的作用域,通过将工作单元注册为PerMatchingScope,它将从为请求创建的作用域中得到解决

如果我错了,请纠正我,否则,有什么区别

此外,如果我将UoW注册为PerLifetimeScope,并且有一个控制台应用程序通过Tcp/Ip向我的web服务器发送需要创建该UoW的Mesages,那么将如何处理它

谢谢

编辑:

public abstract class EFRepository<T> : IRepository<T>
{
    protected readonly DbContext Context;

    public EFRepository(DbContext context)
    {
        Context = context;
    }

    public abstract List<T> Get();

    public void Add(T item)
    {
        Context.Set<T>().Add(item);
    }

    public virtual Remove(T item)
    {
        Context.Set<T>().Remove(item);
    }

    public void Update(T item)
    {
        Context.Entry(item).State = EntityState.Modified;
    }

    public void Dispose()
    {
        Context.Dispose();
    }

    public int SaveChanges()
    {
        return Context.SaveChanges();
    }

    public T FindById(int id)
    {
        return Context.Set<T>().Find(id); 
    }
}

public FoldersRepository : EFRepository<Folder>
{
    public FoldersRepository(DbContext context) : base(context) {}
    . . .
}

// The main part I don't understand
public class mySingletonDataService : ISingletonDataService
{
    private Func<IRepository<Folder>> _foldersRepoFactory;

    public mySingletonDataService(Func<IRepository<Folder>> foldersRepositoryFactory)
    {
        _foldersRepoFactory = foldersRepositoryFactory;
    }

    public void HandleMessageFromTcpIp (Folder folder)
    {
        // will _foldersRepoFactory be Null here, if it reaches here from Tcp/Ip, Will the context in the created repository be null ??
        using (var folder = _foldersRepoFactory())
        {
            ...
        }
    }
}
公共抽象类eRepository:IRepository
{
受保护的只读DbContext上下文;
公共eForepository(DbContext上下文)
{
上下文=上下文;
}
公共摘要列表Get();
公共作废新增(T项)
{
Context.Set().Add(项);
}
公共虚拟删除(T项)
{
Context.Set().Remove(项);
}
公共作废更新(T项)
{
Context.Entry(item).State=EntityState.Modified;
}
公共空间处置()
{
Context.Dispose();
}
公共int SaveChanges()
{
返回Context.SaveChanges();
}
公共T FindById(int id)
{
返回Context.Set().Find(id);
}
}
公共文件夹存储:eRepository
{
公共FoldersRepository(DbContext上下文):基(上下文){}
. . .
}
//主要部分我不明白
公共类mySingletonDataService:ISingletonDataService
{
私人Func_FoldersReportFactory;
公共MySingleToDataService(Func foldersRepositoryFactory)
{
_foldersRepoFactory=foldersRepositoryFactory;
}
来自TCPIP(文件夹)的公用无效HandleMessage
{
//FoldersReportFactory在这里是否为空?如果它从Tcp/Ip到达这里,则创建的存储库中的上下文是否为空??
使用(var folder=\u foldersRepoFactory())
{
...
}
}
}
mySingletonDataService注册为singleton

FoldersRepository注册为PerDependency

DbContext注册为PerRequest?对我的案子有好处吗

Edit2:

我的应用程序结构是:我的容器(LayerContainer是单例的,它保存了应用程序的所有层,因此这些层也是单例的,它们的所有依赖项等等……当应用程序启动时,我解析了我的容器,所有组件也都被解析了。我的问题是,我不知道当我从第一层


希望我的问题是清楚的。来自控制器的DbConext的行为(Http请求)是众所周知的。但是当通过Tcp/Ip处理来自远程应用程序的请求时,DbContext将如何工作?它将按照我们希望的方式作为每个事务的DbContext工作吗?

PerLife Time Scope
每个匹配的生存期范围
每个请求
此顺序从更一般到更具体

每个请求
为每个匹配的生存期范围创建标记为
的“请求”
并为您管理生存期

每个匹配的生存期作用域
创建标记的
每个生存期作用域
。如果您有嵌套的生存期作用域,这是合适的。 如果向此作用域注册类型,则无法在另一个没有相同标记的生存时间范围中解析该类型(父生存时间范围也没有此标记)。因此,它为您提供了对每个生存时间范围
的更多控制

每个生存期范围
创建一个对象,该对象由同一生存期范围内的所有人共享

每次解析时,
每个依赖项都会创建不同的对象。这不是共享的

如果我们来问您的问题:

每次
\u foldersrepopfactory()
都被称为新的
FoldersRepository
对象,并且在基类构造函数中创建
DbContext
对象。但是
DbContext
对象只是在一个请求中创建一次,并由所有其他人共享

为了更好地解释,我在您的方法中又使用了一个
\u foldersRepoFactory()

  public void HandleMessageFromTcpIp (Folder folder)
        {
            // will _foldersRepoFactory be Null here, if it reaches here from Tcp/Ip, Will the context in the created repository be null ??
            using (var folder = _foldersRepoFactory())
            {
                ...
            }

 using (var folder = _foldersRepoFactory())
            {
                ...
            }
        }
假设您有一个请求,并在此请求中解析了
mySingletonDataService
。第一个Autofac容器创建了
mySingletonDataService
(如果未创建),这将一直保留

对于第一个调用的
\u foldersRepoFactory()
,Autofac容器将创建新的
FoldersRepository
DbContext
对象

对于第二个调用的
\u foldersRepoFactory()
,Autofac容器装箱新的
FoldersRepository
对象,但它使用之前创建的
DbContext
对象(不是新的
DbContext
),因为它们在相同的请求生命周期范围内

请求完成后,您的
mySingletonDataService
对象保留;您的2
FoldersRepository
和1
DbContext
对象被释放(假设GC收集)

由于第1层的原因,您不能对每个请求使用
。您可以对每个生存期范围使用
。对于第3层,它将在请求生存期范围内解析,因此它将像对每个请求使用
。在解析第1层中的类型时,您应该小心。您应该开始新的生存期范围

除此之外,一切都正常,因为您使用的是
Func
,所以它不会坚持使用singleton

注: 您能否将其设置为只读,以确保我们不会在运行时更改它

 private Func<IRepository<Folder>> _foldersRepoFactory;
private Func\u foldersrepoofactory;

每个生命周期时间范围
每个匹配生命周期范围
每个请求
此顺序从更一般到更具体

每个请求
创建每个匹配生存期标记的“请求”