c# - 依赖项注入(inject) ASP.NET Identity 用户(和单元测试)

标签 c# dependency-injection asp.net-identity razor-pages

我不完全理解如何重构我的应用以使其更易于测试。

我正在使用 ASP.NET Core 3.0(Razor Pages,如果重要的话)。

当前状态:

我有在我的上下文(继承自 IdentityDbContext)和 userManager 中注入(inject)的 Razor 页面模型:

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();
    }

我创建了具有如下构造函数的存储库:

public MyRepository(ApplicationDbContext context, AVUser user) 

我从不直接在我的模型类中使用上下文,而是使用传入的上下文在模型类中创建存储库。在这种情况下,ApplicationDbContext 是我的 EF Core 上下文,AVUser 是我的身份用户类型,定义为:

public class AVUser : IdentityUser

我的 DI 设置为:

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


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

我不明白的地方

我想让我的 razor 页面模型类可以单元测试而不依赖于数据库或存储库类,模拟存储库类,所以我希望我必须从构造函数中删除上下文,而是为我的存储库和 DI 创建接口(interface)他们。

但是,我不知道如何在存储库的用户参数中进行 DI - 如何在 Startup.cs 中设置我的服务以便可以传入?今天为了获得这个值(value),我运行:

AVUser = await _userManager.GetUserAsync(User);

最佳答案

如果您在 DI 容器中注入(inject)您的存储库,IoC 将自动注入(inject)它们的依赖项,例如 Controller 和页面。所以你只需要在你的存储库类中有一个这样的构造函数:

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

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

然后注入(inject)到容器中:

services.AddTransient<IMyRepository,MyRepository>();

就是这样。 请记住为您的存储库创建一个接口(interface),以便您可以为生产或测试注入(inject)不同的实例。尽管如此,您不应该依赖 DI 进行测试。如果您正在编写单元测试,那么为您的 MyRepository 创建一个测试实现并简单地实例化它。如果您正在编写集成测试,那么您必须使用不同的 sturtup 类。

关于c# - 依赖项注入(inject) ASP.NET Identity 用户(和单元测试),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58864059/

相关文章:

c# - 采用接口(interface)+抽象类的继承设计。好的做法?

c# - 谷歌驱动器 API : I have to fetch only files in that folder without trashed files

asp.net - 如何使用依赖注入(inject)将工作单元容器传递到存储库的构造函数中

c# - ASP.NET Core Identity,如何覆盖 IdentityRole 名称唯一索引?我想存储关于租户的重复名称

asp.net-core - 在身份服务器 4 中成功验证后如何在应用程序级别授权用户

asp.net-mvc - 如何在 MVC5 中为用户分配角色?

c# - 从数据库面向对象?

c# - 如何查看帖子数据

javascript - 将依赖项指定为字符串是否会使 AngularJS 中的 DI 更快?

android - Dagger 2 : Cannot resolve symbol for dagger component