【问题标题】:looking for samples on how to user services.add* in asp.vnext寻找有关如何在 asp.vnext 中使用 services.add* 的示例
【发布时间】:2015-02-14 14:55:45
【问题描述】:

我想知道在哪里可以找到解释services.AddInstanceservices.AddScopedservices.AddSingletonservice.AddTransient 之间差异的示例。

我发现一些文章以通用的方式解释了这一点,但我认为源示例更清楚。

【问题讨论】:

  • 是的,我已经读过了,但我无法理解范围生活方式的含义。查看我看到的主要来自实体框架的来源。举个例子,如果我需要通过 DI 添加一个在对象上下文的生命周期内保持自己状态的实体,我必须在 db xontext?这样,如果我打开不同 dbcontext 的相同实例的两个不同实例,我想每个实例都会保持自己的状态。

标签: asp.net-core


【解决方案1】:

这个问题的范围相当大,但由于您似乎专门在寻找 AddScoped 信息,因此我将示例范围缩小到 Web 应用程序内的范围。

在 Web 应用程序中 AddScoped 几乎意味着请求的范围。 EntityFramework 在内部使用范围,但在大多数情况下它不会影响用户代码,所以我坚持使用用户代码,如下所示。

如果您将DbContext 注册为服务,并且还注册了范围服务,那么对于每个请求,您将获得一个范围服务的单个实例,您可以在其中解析DbContext

下面的示例代码应该更清楚。一般来说,我建议按照我在下面展示的方式尝试一下,以通过调试器中的代码逐步熟悉行为。从一个空的 Web 应用程序开始。请注意,我显示的代码来自 Beta2(因为在 Beta2 中我们添加了[FromServices] 属性,这使得演示更容易,无论版本如何,基本行为都是相同的。

startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // Add EF services to the services container.
    services.AddEntityFramework(Configuration)
        .AddSqlServer()
        .AddDbContext<UserDbContext>();

    services.AddScoped<UserService>();

    // Add MVC services to the services container.
    services.AddMvc();
}

UserDbContext.cs

public class UserDbContext : DbContext
{
    public UserService UserService { get; }

    public UserDbContext(UserService userService)
    {
        _userService = userService;
    }
}

HomeController.cs

public class HomeController : Controller
{
    private UserDbContext _dbContext;
    public HomeController(UserDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public string Index([FromServices]UserDbContext dbContext, [FromServices]UserService userService)
    {
        // [FromServices] is available start with Beta2, and will resolve the service from DI
        // dbContext == _ctrContext
        // and of course dbContext.UserService == _ctrContext.UserService;

        if (dbContext != _dbContext) throw new InvalidOperationException();
        if (dbContext.UserService != _dbContext.UserService) throw new InvalidOperationException();
        if (dbContext.UserService != userService) throw new InvalidOperationException();

        return "Match";
    }
}

或者,如果您从另一个服务解析用户服务,这一次注册为 transient 瞬态服务将在每次解析时都有一个新实例,但范围内的服务将在 请求范围。

创建新的服务

public class AnotherUserService
{
    public UserService UserService { get; }

    public AnotherUserService(UserService userService)
    {
        UserService = userService;
    }
}

将以下行添加到 startup.cs

services.AddTransient<AnotherUserService>();

并重写HomeController.cs如下 公共类 HomeController : 控制器 { 私有AnotherUserService _anotherUserService;

    public HomeController(AnotherUserService anotherUserService)
    {
        _anotherUserService = anotherUserService;
    }

    public string Index([FromServices]AnotherUserService anotherUserService,
                        [FromServices]UserService userService)
    {
        // Since another user service is tranient we expect a new instance
        if (anotherUserService == _anotherUserService)
            throw new InvalidOperationException();

        // but the scoped service should remain the same instance
        if (anotherUserService.UserService != _anotherUserService.UserService)
            throw new InvalidOperationException();
        if (anotherUserService.UserService != userService)
            throw new InvalidOperationException();

        return "Match";
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多