Autofac PerLifetimeScope VS PerRequest在Web应用程序 [英] Autofac PerLifetimeScope vs PerRequest in web applications

查看:216
本文介绍了Autofac PerLifetimeScope VS PerRequest在Web应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Autofac DI盛载

Using Autofac DI container-

是什么在我的web应用程序注册一个工作单元按要求注册为PerLifetimeScope区别呢?

What is the difference between registering a unit of work in my web application as per request to registering it as PerLifetimeScope?

Autofac会为每个请求,并通过注册工作单元作为PerMatchingScope它将反正从用于请求创建的范围来解决新的范围。

Autofac creates a new scope for each request and by registering the unit of work as PerMatchingScope it will anyways be resolved from the scope created for the request.

如果我错了,请大家指正,否则,有什么区别?

If I'm mistaken, please correct me, otherwise, what is the difference?

此外,如果我注册为UOW PerLifetimeScope,并发送通过TCP / IP mesaages到需要UOW的创建我的Web服务器,它将如何处理一个控制台应用程序?

Moreover, If I register the UoW as PerLifetimeScope, and have a console application that sends mesaages over Tcp/Ip to my web server that require creation of that UoW, how will it be handled?

谢谢!

编辑:

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

mySingletonDataService注册为单身,

mySingletonDataService registered as singleton,

注册为PerDependency FoldersRepository,

FoldersRepository registered as PerDependency,

临时用户的DbContext作为PerRequest?这是好我的情况?

DbContext registed as PerRequest? Is it good for my case?

EDIT2:

我的应用程序的结构是这样的:我的容器(LayersContainer是单身,并持有所有应用程序层,所以层也单身及其所有的依赖等等......当应用程序启动我解决我的容器中,所有组件都解决为好。我的问题是,我不知道如何当我从Layer1的的SingletonDataService的DbContexts的行为。

My application structure is this: my container (LayersContainer is singleton and holds all the application's layers, therefore the layers are also singleton and all their dependencies and so on... When application starts I resolve my container and all the components are resolved as well. My problem is that I don't know how the DbContexts will behave when I get to the SingletonDataService from Layer1.

在这里输入的形象描述

希望我的问题是清楚的。在DbConext从控制器(HTTP请求)的行为是相当知名。但是,如何将处理来自通过TCP / IP远程应用程序的请求时,DbContexts表现?它将作为每笔交易的DbContext工作,因为我们希望它的工作?

Hope my problem is clear. The behavior of the DbConext from controllers (Http requests) is quite known. But how will the DbContexts behave when handling requests from the remote application over Tcp/Ip? Will it work as DbContext per transaction as we want it to work?

推荐答案

PerLife时间范围> 每匹配终身范围> 每请求这个命令更一般到更具体。

PerLife Time Scope>Per Matching Lifetime Scope>Per Request this order more general to more specific.

每请求创建请求功能标签每匹配终身范围,并为你管理的一生。

Per Request creates 'request' taged Per Matching Lifetime Scope and it manages lifetime for you.

每匹配终身范围创建功能标签 PerLifeTimeScope 。这是合适的,如果你有嵌套续航时间范围。
如果你注册这个范围类型,你可以不解决不具有相同的标签(也母公司lifetimescopes没有这个标签)另一种生活时间波谱的类型。所以,它给你的更多的控制每生命期范围

Per Matching Lifetime Scope creates taged PerLifeTimeScope. This is suitable, if you have nested life time scopes. If you register a type with this scope, you can't resolve the type in another life timescope which does not have same tag (which also parent lifetimescopes do not have this tag). So it gives you more control on Per LifeTime Scope.

每生命期范围创建一个对象,该对象是所有在同一lifetimescope共享。

Per LifeTime Scope creates an object and the object is shared by all in same lifetimescope.

每Depency 当你解决创建一个不同的对象每次。这是不共享的。

Per Depency creates a different object everytime when you resolve. This is not shared.

如果我们进来你的问题:

每次 _foldersRepoFactory()被称为新的 FoldersRepository 对象被创建和的DbContext 对象是在你的基类的构造函数创建的。但的DbContext 对象刚刚创建1次的请求,并赞同所有其他人。

Everytime _foldersRepoFactory() is called new FoldersRepository object is created and DbContext object is created in your base class constructor. But DbContext object is just created 1 time in a request and shared by all others.

我用多了一个 _foldersRepoFactory()在你的方法,以更好地解释。

I use one more _foldersRepoFactory() in your method to explain better.

  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 (如果它没有创建)这一切停留续航时间。

Let's say you have a request and you resolve mySingletonDataService in this request. First Autofac container creates mySingletonDataService (if it's not created) this stays all life time.

有关第一个 _foldersRepoFactory()被调用时,Autofac容器创建新的 FoldersRepository 的DbContext 的对象。

For first _foldersRepoFactory() is called, Autofac Container creates new FoldersRepository and DbContext objects.

有关二 _foldersRepoFactory()被调用,Autofac容器包装箱新的 FoldersRepository 对象,但之前<$使用C $ C>的DbContext 对象(而不是新的的DbContext 创建),因为它们都在同一个请求续航时间范围。

For Second _foldersRepoFactory() is called, Autofac Container crates new FoldersRepository object but it uses the before DbContext object (not new DbContext is created) because they are in same request life time scope.

请求完成后,你的 mySingletonDataService 对象停留;您2 FoldersRepository 1 的DbContext 对象被设置(假设GC收集)。

After request finished, your mySingletonDataService object stays; your 2 FoldersRepository and 1 DbContext objects is disposed (Let's assume GC collects).

您不能使用每请求,因为1层可以使用每终生范围。对于3层将在请求生命周期范围内解决,这样它会像每请求。你应该小心,而在Layer1的解决您的类型,你开始前人的精力新lifetimescope。

You can't use Per Request because of Layer 1. You can use Per Lifetime Scope. For Layer 3 it will resolved in request lifetime scope so it will act like Per Request. You should be careful while resolving your type in Layer1 you sould begin new lifetimescope.

除此之外全部的寄托是好的,因为你正在使用 Func键&LT; IRepository&LT;文件夹&GT;&GT; 所以它不会与单贴

Other than this everthing is ok because you are using Func<IRepository<Folder>> so it will not stick with singleton.

请注意:
你可以把它只读,以确保我们不会在运行时改变它。

Note: Can you make it readonly to be sure we are not changing it at runtime.

 private Func<IRepository<Folder>> _foldersRepoFactory;

这篇关于Autofac PerLifetimeScope VS PerRequest在Web应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆