依赖项注入 ASP.NET 身份用户(和单元测试)
Dependency injecting an ASP.NET Identity user (and unit testing)
我不完全理解如何重构我的应用程序以使其更易于测试。
我正在使用 ASP.NET Core 3.0(Razor Pages,如果重要的话)。
当前状态:
我有在我的上下文(继承自 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();
}
我创建了具有如下构造函数的存储库:
public MyRepository(ApplicationDbContext context, AVUser user)
我从不直接在模型 classes 中使用上下文,而是使用传入的上下文在模型 classes 中创建存储库。在这种情况下,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 页面模型 classes 在不依赖数据库或存储库 classes 的情况下进行单元测试,模拟存储库 class,所以我希望我有从构造函数中删除上下文,而是为我的存储库创建接口并对它们进行 DI。
但是,我不知道如何在存储库的用户参数中进行 DI - 如何在 Startup.cs 中设置我的服务以便可以传入?今天为了得到这个值,我 运行:
AVUser = await _userManager.GetUserAsync(User);
如果您在 DI 容器中注入您的存储库,IoC 将自动注入它们的依赖项,例如控制器和页面。所以你只需要在你的存储库中有一个这样的构造函数 class:
private readonly ApplicationDbContext _context;
private readonly UserManager<AVUser> _userManager;
public MyRepository(ApplicationDbContext context, UserManager<AVUser> userManager)
{
_context = context;
_userManager = userManager;
}
然后注入到容器中:
services.AddTransient<IMyRepository,MyRepository>();
就是这样。
请记住为您的存储库创建一个接口,以便您可以为生产或测试注入不同的实例。尽管如此,您不应该依赖 DI 进行测试。如果您正在编写单元测试,那么为您的 MyRepository 创建一个测试实现并简单地实例化它。如果您正在编写集成测试,那么您必须使用不同的 sturtup
class.
我不完全理解如何重构我的应用程序以使其更易于测试。
我正在使用 ASP.NET Core 3.0(Razor Pages,如果重要的话)。
当前状态:
我有在我的上下文(继承自 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();
}
我创建了具有如下构造函数的存储库:
public MyRepository(ApplicationDbContext context, AVUser user)
我从不直接在模型 classes 中使用上下文,而是使用传入的上下文在模型 classes 中创建存储库。在这种情况下,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 页面模型 classes 在不依赖数据库或存储库 classes 的情况下进行单元测试,模拟存储库 class,所以我希望我有从构造函数中删除上下文,而是为我的存储库创建接口并对它们进行 DI。
但是,我不知道如何在存储库的用户参数中进行 DI - 如何在 Startup.cs 中设置我的服务以便可以传入?今天为了得到这个值,我 运行:
AVUser = await _userManager.GetUserAsync(User);
如果您在 DI 容器中注入您的存储库,IoC 将自动注入它们的依赖项,例如控制器和页面。所以你只需要在你的存储库中有一个这样的构造函数 class:
private readonly ApplicationDbContext _context;
private readonly UserManager<AVUser> _userManager;
public MyRepository(ApplicationDbContext context, UserManager<AVUser> userManager)
{
_context = context;
_userManager = userManager;
}
然后注入到容器中:
services.AddTransient<IMyRepository,MyRepository>();
就是这样。
请记住为您的存储库创建一个接口,以便您可以为生产或测试注入不同的实例。尽管如此,您不应该依赖 DI 进行测试。如果您正在编写单元测试,那么为您的 MyRepository 创建一个测试实现并简单地实例化它。如果您正在编写集成测试,那么您必须使用不同的 sturtup
class.