我正在尝试将最近发布的ASP.NET Identity 2.0.0集成到一个三层MVC应用程序中。我不确定我的方向是否正确。我可以采取两种方法。
在第一种方法中,我将Identity集成到每个逻辑层中。集成了一些技术问题,但仍在发展中。
在第二种方法中,使用专门用于安全性的自包含封装程序集。
我现在已经采用了方法1,但对它提出了质疑。此外,还有其他方法吗?
方法1
Web
Startup.cs
/App_Start/Startup.Auth
/Controllers/Account
/Controllers/Manage
/Controllers/RolesAdmin
/Controllers/UserAdmin
/ViewModels
/Views
Business Logic
/Service/AccountService
/Service/ApplicationRoleManager
/Service/ApplicationUserManager
/Service/EmailService
/Service/SmsService
/Service/SignInHelper
Data
ApplicationDbContext
ApplicationUser
所以,我只是简单地取了Identity,并将其插入到我认为合适的每一层中。我把大部分日志放在了业务逻辑层,因为它不属于Web,也没有"真正的"数据库代码可以让它属于数据层。
次要问题:我有点不舒服,在Web/App_Start/Startup.Auth中,我必须实例化Busness Logic对象才能调用
app.CreatePerOwinContext(ApplicationDbContext.Create);
在数据层中。我还没有进一步考虑这个问题。这是另一个问题(但我认为这与我选择的体系结构有关(。
方法2
创建一个不包含任何层的纯安全程序集,即只需将Identity 2.0.0插入该程序集。我的申请可以参考这一点。不过,它违反了层次。但它封装了安全性。考虑到安全对象可以(或应该(在整个应用程序生命周期中驻留,这似乎不是一个坏主意。但还没有考虑可伸缩性。
我采用了方法1,在创建上下文时,我有一个助手类,我试图从HttpContext.Current.["DbActiveContext"]中获取上下文,并在它存在的情况下使用它,如果不存在,则创建新的上下文,并为整个应用程序使用单个上下文。因此,您不会为aspnet标识创建一个上下文,而为应用程序的其余部分创建另一个上下文。在第一种方法中,您似乎正在尝试使用存储库模式,如果是这样的话,那么您的身份模型应该在DB层中,而对于完整的存储库模式来说,您应该在创建对象时使用依赖项注入,这样做,在运行时创建对象之前,您将不会有依赖项。
namespace Data.Common
{
public class ConnectionHelper : IConnectionHelper
{
private ApplicationDbContext _context;
public ApplicationDbContext Context
{
get
{
if (_context == null && HttpContext.Current.Items["DbActiveContext"] != null)
{
_context = (ApplicationDbContext)HttpContext.Current.Items["DbActiveContext"];
}
else if (_context == null && HttpContext.Current.Items["DbActiveContext"] == null)
{
_context = new ApplicationDbContext();
HttpContext.Current.Items.Add("DbActiveContext", _context);
}
return _context;
}
set { _context = value; }
}
}
}
此外,如果您想在服务层中使用带有DI的用户管理器,您可以执行以下操作:
public UserController()
: this(
new ApplicationUserManager(new UserStore<ApplicationUser>(new ConnectionHelper().Context)),
new UserService())
{
}
带有UserService签名,如:
public class UserService
{
private readonly IRepository<ApplicationUser> _user;
private readonly UserManager<ApplicationUser> _userManager;
public UserService(IRepository<ApplicationUser> user,
UserManager<ApplicationUser> userManager)
{
_user = user;
_userManager = userManager;
}
public UserService()
: this(
new Repository<ApplicationUser>(new ConnectionHelper()),
new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ConnectionHelper().Context)))
{
}
我希望这对你有帮助!