首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >依赖项注入ASP.NET标识用户(和单元测试)

依赖项注入ASP.NET标识用户(和单元测试)
EN

Stack Overflow用户
提问于 2019-11-14 19:03:32
回答 1查看 922关注 0票数 2

我不完全理解如何重构我的应用程序,使它更易测试。

我正在使用ASP.NET Core3.0 (Razor,如果这很重要)。

现状:

我有在上下文中注入(从IdentityDbContext继承的)和userManager的剃刀页面模型:

代码语言:javascript
运行
复制
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();
    }

我创建了存储库,其构造函数如下:

代码语言:javascript
运行
复制
public MyRepository(ApplicationDbContext context, AVUser user) 

我从不在Model类中直接使用上下文,而是使用传入的上下文在Model类中创建存储库。在本例中,ApplicationDbContext是我的EF核心上下文,AVUser是我的身份用户类型,定义为:

代码语言:javascript
运行
复制
public class AVUser : IdentityUser

我的DI设置为:

代码语言:javascript
运行
复制
// DB Setup
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));


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

我不懂的

我想让自己的剃须刀页面模型类在不依赖数据库或存储库类的情况下具有可测试性,从而模拟存储库类,因此我希望我必须从构造函数中删除上下文,而是为我的存储库和DI创建接口。

但是,我不知道如何在Repository的用户参数中进行DI --如何在Startup.cs中设置我的服务,这样就可以传递它了?今天,为了获得这个值,我运行:

代码语言:javascript
运行
复制
AVUser = await _userManager.GetUserAsync(User);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-14 19:38:13

如果在DI容器中注入存储库,IoC将自动注入它们的依赖项,如控制器和页面。因此,您只需要在存储库类中有这样的构造函数:

代码语言:javascript
运行
复制
private readonly ApplicationDbContext _context;
private readonly UserManager<AVUser> _userManager;

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

然后将其注入容器:

代码语言:javascript
运行
复制
services.AddTransient<IMyRepository,MyRepository>();

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58864059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档