如何使用 Microsoft Identity Framework 从基础 C# 基础项目中抽象依赖类型?
How can I abstract dependent type from base C# base project using microsoft identity framework?
我有一个我想重复使用的身份验证项目。
我有一个名为 authentication 的 AspNetCore Identity 项目,它旨在成为一个可重用的身份验证项目。如果您看过 AspNetCore Identity 实现,您会看到一个名为 UserManager 的类型,其中应用程序用户是 class,您将用户的实现存储在 AspNetUsers 数据库 table 中。
public class ApplicationUser : IdentityUser
{
}
我遇到的问题是,在这个名为 AccountController 的独立身份验证项目中有一个控制器,它包含所有日志记录 in/out、注册和其他相关帐户操作。我希望从这个项目的class中抽象出应用程序用户,以便我可以根据项目的需要更改它以获得多个解决方案。
身份验证项目有一个启动项 class,它在使用它的项目中按如下方式启动:
authenticationStartUp.ConfigureServices<ApplicationUser, MyDatabase>
(services, Configuration);
如您所见,订阅项目添加了自己的 ApplicationUser 实现。接下来是在 services.AddIdentity 调用中引用 TApplicationUser 的身份配置。
public void ConfigureServices<TApplicationUser, TContext>
(IServiceCollection services, IConfigurationRoot Configuration)
where TApplicationUser : IdentityUser
where TContext : DbContext
{
services.AddIdentity<TApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<TContext>()
.AddDefaultTokenProviders();
不幸的是,这现在在使用注入服务的 AccountController 中出现故障。如何将 TApplicationUser 添加到控制器中。
public class AccountController : Controller
{
private readonly UserManager<TApplicationUser> _userManager;
public AccountController(UserManager<TApplicationUser> userManager)
{
_userManager = userManager;
}
}
这显然是错误的,因为没有 TApplicationUser。此外,如果我按如下方式添加 TApplicationUser,则控制器不再解析并且什么也没有发生。
public class AccountController<TApplicationUser> : Controller
where TApplicationUser : IdentityUser
{
private readonly UserManager<TApplicationUser> _userManager;
public AccountController(UserManager<TApplicationUser> userManager)
{
_userManager = userManager;
}
}
是否仍然可以使用包含的类型参数来解析应用程序控制器?
而且,我还发现了另一个问题,即使我在基础中添加了类型参数 class 我如何才能在使用 TApplicationUser 的视图中添加类型参数。这是一个例子
查看嵌入在认证项目中
@* TApplicationUser obviously doesn't resolve *@
@inject SignInManager<TApplicationUser> SignInManager
@{
var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
if (loginProviders.Count == 0)
{
<div>
<p>
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
}
else
{
<form asp-controller="Account" asp-action="ExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
<div>
<p>
@foreach (var provider in loginProviders)
{
<button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button>
}
</p>
</div>
</form>
}
}
将通用控制器作为基础控制器存在于可重用项目中
public abstract class AccountControllerBase<TApplicationUser> : Controller
where TApplicationUser : IdentityUser {
protected readonly UserManager<TApplicationUser> _userManager;
protected AccountController(UserManager<TApplicationUser> userManager) {
_userManager = userManager;
}
}
using class/project 将从基本控制器派生并定义通用参数
public class AccountController : AccountControllerBase<ApplicationUser> {
public AccountController(UserManager<ApplicationUser> userManager)
: base(userManager) { }
}
我有一个我想重复使用的身份验证项目。
我有一个名为 authentication 的 AspNetCore Identity 项目,它旨在成为一个可重用的身份验证项目。如果您看过 AspNetCore Identity 实现,您会看到一个名为 UserManager 的类型,其中应用程序用户是 class,您将用户的实现存储在 AspNetUsers 数据库 table 中。
public class ApplicationUser : IdentityUser
{
}
我遇到的问题是,在这个名为 AccountController 的独立身份验证项目中有一个控制器,它包含所有日志记录 in/out、注册和其他相关帐户操作。我希望从这个项目的class中抽象出应用程序用户,以便我可以根据项目的需要更改它以获得多个解决方案。
身份验证项目有一个启动项 class,它在使用它的项目中按如下方式启动:
authenticationStartUp.ConfigureServices<ApplicationUser, MyDatabase>
(services, Configuration);
如您所见,订阅项目添加了自己的 ApplicationUser 实现。接下来是在 services.AddIdentity 调用中引用 TApplicationUser 的身份配置。
public void ConfigureServices<TApplicationUser, TContext>
(IServiceCollection services, IConfigurationRoot Configuration)
where TApplicationUser : IdentityUser
where TContext : DbContext
{
services.AddIdentity<TApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<TContext>()
.AddDefaultTokenProviders();
不幸的是,这现在在使用注入服务的 AccountController 中出现故障。如何将 TApplicationUser 添加到控制器中。
public class AccountController : Controller
{
private readonly UserManager<TApplicationUser> _userManager;
public AccountController(UserManager<TApplicationUser> userManager)
{
_userManager = userManager;
}
}
这显然是错误的,因为没有 TApplicationUser。此外,如果我按如下方式添加 TApplicationUser,则控制器不再解析并且什么也没有发生。
public class AccountController<TApplicationUser> : Controller
where TApplicationUser : IdentityUser
{
private readonly UserManager<TApplicationUser> _userManager;
public AccountController(UserManager<TApplicationUser> userManager)
{
_userManager = userManager;
}
}
是否仍然可以使用包含的类型参数来解析应用程序控制器?
而且,我还发现了另一个问题,即使我在基础中添加了类型参数 class 我如何才能在使用 TApplicationUser 的视图中添加类型参数。这是一个例子
查看嵌入在认证项目中
@* TApplicationUser obviously doesn't resolve *@
@inject SignInManager<TApplicationUser> SignInManager
@{
var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
if (loginProviders.Count == 0)
{
<div>
<p>
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
}
else
{
<form asp-controller="Account" asp-action="ExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
<div>
<p>
@foreach (var provider in loginProviders)
{
<button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button>
}
</p>
</div>
</form>
}
}
将通用控制器作为基础控制器存在于可重用项目中
public abstract class AccountControllerBase<TApplicationUser> : Controller
where TApplicationUser : IdentityUser {
protected readonly UserManager<TApplicationUser> _userManager;
protected AccountController(UserManager<TApplicationUser> userManager) {
_userManager = userManager;
}
}
using class/project 将从基本控制器派生并定义通用参数
public class AccountController : AccountControllerBase<ApplicationUser> {
public AccountController(UserManager<ApplicationUser> userManager)
: base(userManager) { }
}