简体   繁体   English

依赖注入 ASP.NET 身份用户(和单元测试)

[英]Dependency injecting an ASP.NET Identity user (and unit testing)

I don't fully understand how to refactor my app to make it more testable.我不完全了解如何重构我的应用程序以使其更具可测试性。

I am using ASP.NET Core 3.0 (Razor Pages, if that matters).我正在使用 ASP.NET Core 3.0(Razor Pages,如果重要的话)。

Current State:当前 State:

I have razor pages models that inject in my context (inherited from IdentityDbContext) and userManager:我有 razor 页面模型在我的上下文中注入(继承自 IdentityDbContext)和 userManager:

public class DashboardModel : PageModel
{

    private readonly ApplicationDbContext _context;
    private readonly UserManager<AVUser> _userManager;

    public DashboardModel(ApplicationDbContext context, UserManager<AVUser> userManager)
    {
        _context = context;
        _userManager = userManager;
    }
    public async Task<IActionResult> OnGetAsync()
    {
        AVUser = await _userManager.GetUserAsync(User);
        MyRepository myRepository = new MyRepository(_context, AVUser);

        // omitted - just getting data from the repository for use on the page

        return Page();
    }

I have repositories created who have constructors as the following:我创建了具有以下构造函数的存储库:

public MyRepository(ApplicationDbContext context, AVUser user) 

I never use the context directly in my Model classes and instead create repositories in the Model classes using the context passed in. In this case ApplicationDbContext is my EF Core context, and AVUser is my type of Identity User, defined as:我从不直接在我的 Model 类中使用上下文,而是使用传入的上下文在 Model 类中创建存储库。在这种情况下,ApplicationDbContext 是我的 EF Core 上下文,AVUser 是我的身份用户类型,定义为:

public class AVUser : IdentityUser

My DI is set up as:我的 DI 设置为:

// DB Setup
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));


// Identity Setup
        services.AddDefaultIdentity<AVUser>(config =>
        {
            config.SignIn.RequireConfirmedEmail = true; 
        })
        .AddEntityFrameworkStores<ApplicationDbContext>();

What I don't understand我不明白的

I want to make my razor pages model classes unit testable without relying on the database or repository classes, mocking up the repository class, so I expect I have to remove the context from the constructor and instead created interfaces for my repositories and DI them. I want to make my razor pages model classes unit testable without relying on the database or repository classes, mocking up the repository class, so I expect I have to remove the context from the constructor and instead created interfaces for my repositories and DI them.

However, I don't know how to DI in the user parameter for the Repository - how do I set up my service in Startup.cs so this can get passed in?但是,我不知道如何在存储库的用户参数中进行 DI - 如何在 Startup.cs 中设置我的服务以便可以传入? Today to get the value for this, I run:今天为了得到这个值,我运行:

AVUser = await _userManager.GetUserAsync(User);

If you inject your repositories in the DI container, IoC will automatically inject their dependencies like controllers and pages.如果您在 DI 容器中注入存储库,IoC 将自动注入它们的依赖项,例如控制器和页面。 so you just need to have a constructor like this in your repository class:所以你只需要在你的存储库 class 中有一个这样的构造函数:

private readonly ApplicationDbContext _context;
private readonly UserManager<AVUser> _userManager;

public MyRepository(ApplicationDbContext context, UserManager<AVUser> userManager)
{
    _context = context;
    _userManager = userManager;
}

and then inject it to the container:然后将其注入容器:

services.AddTransient<IMyRepository,MyRepository>();

and that's it.就是这样。 remember to create an interface for your repository so you can inject different instances for either production or testing.请记住为您的存储库创建一个接口,以便您可以为生产或测试注入不同的实例。 Nonetheless, You shouldn't rely on DI for testing.尽管如此,您不应该依赖 DI 进行测试。 If you are writing unit tests then create a test implementation for your MyRepository and simply instantiate it.如果您正在编写单元测试,那么为您的 MyRepository 创建一个测试实现并简单地实例化它。 If you are writing integration tests then you have to use a different sturtup class.如果您正在编写集成测试,那么您必须使用不同的sturtup class。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM