entity-framework – 数据层中的IdentityUser
我正在努力设计(或过度设计)我正在做的网络项目.
我有一个MyProject.Data,MyProject.Business和MyProject.Web DLL. 我的数据层(基于EF6)包含我的实体,db context. 我的业务层包含我的存储库(是的,可能不是真正的repo模式). 我已经将IdentityFramwork添加到Web项目中,并且cource创建了ApplicationUser.我的数据层中已有用户POCO.我想将Application用户移动到Data层,因此我可以将它与其他实体一起使用. 一种方法是让我的Data.User扩展IdentityUser,并让我的Data.MyContext扩展IdentityDbContext.这导致数据层与asp.net.identity框架强烈耦合,这种框架感觉不太对劲. 这里的最佳做法是什么? 解决方法
我不建议用户扩展ApplicationUser.我认为ApplicationUser只是用户可以访问您的应用程序的方式(通过电子邮件登录并通过Facebook,谷歌).您的用户实体属于您的域,因此您不需要密码(作为示例).实际上,单个用户可以关联许多ApplicationUser,为什么同一个用户不能使用differente帐户登录?
可以让你的数据层引用Identity的dll,你多久会在你的项目中改变它?我真诚地从未见过这种情况,一旦你把一个项目运行到一个已定义的框架,你很少改变它,当然你的应用程序可能会增长,但你很少需要改变这样的事情.这样,您的数据层不会耦合到Web项目,而是耦合到库(如提到的sunil). AspNetUser的表将存在,但WPF项目不一定需要将其用作登录方法 此外,我建议您将实体保留在业务层中(我也鼓励不在那里使用DataAnnotations),然后使用Fluent API使您的数据层使用Entity Framework映射它们,并将EF封装在您的Concrete Repositories中,这应该在数据层只是从业务层实现存储库接口. 使您的DBContext扩展IdentityDbContext,但不要使您的用户扩展ApplicationUser,您可以使ApplicationUser具有User.每当新用户登录您通常创建新ApplicationUser的应用程序时,您也可以创建用户并与之关联.一旦记录,该用户可以将另一个外部登录关联到他的帐户(这意味着许多ApplicationUser到同一个用户).
业务层 – 不应该知道其他层,它是最简单的,应该表达您的真实业务,并成为无所不在的语言的一部分 public class User: ITrackable { public int ID { get; protected set; } public string Name { get; set; } public string Description { get; set; } public UserStatus Status { get; set; } public DateTime? Birthday { get; set; } public virtual ICollection<Address> Addresses { get; protected set; } public string LastKnownPlace { get; set; } public virtual bool IsPremium() { // some logic } public string GetTrackingIdentification() { // gets some unique key representing this object. Shouldn't be ID,since I might track other objects,soon IDs would dup for different objects... } } public interface ITrackable { string GetTrackingIdentification(); string LastKnownPlace { get; set; } } public interface ITrackingService<T> where T: ITrackable { void Track(IEnumerable<T> source); } public interface IUserTrackingService: ITrackingService<User> { IEnumerable<User> GetDeadbetUsersWithTracking(); } public interface IUserRepository { IEnumerable<User> GetPremiumUsers(); IEnumerable<User> GetDeadbets(); } 基础架构层 – 应该处理应用程序请求的操作应该如何执行.它可以通过实现存储库来使用数据库持久性,可以使用实体框架或任何其他提供程序,也可以写入文本文件,排队任务,发送电子邮件,记录,也可以写入注册表,这些可以称为Infra服务.在这里你应该引用Business层,你也可以引用Identity的dll.为了简单起见,我只是实现了存储库: public class YourContext : IdentityDbContext<ApplicationUser> { DbSet<User> DomainUsers { get; set; } DbSet<Address> Addresses { get; set; } public YourContext(): base("DefaultConnection",throwIfV1Schema: false) { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<IdentityRole>().Property(r => r.Name).HasMaxLength(200); modelBuilder.Entity<ApplicationUser>().Property(a => a.UserName).HasMaxLength(200); modelBuilder.Entity<User>().Property(u => u.Name).IsRequired().HasMaxLength(50); } } 服务层 – 将引用Businness和Infra层,实现业务服务.服务在这里是一个含糊不清的术语.有应用程序服务,域服务和Infra服务.域服务是一种复杂/通用操作,它是业务逻辑的一部分,但不属于特定实体.应用程序服务是一种通过API,WCF等向外部世界公开操作的方法.我之前解释过的Infra服务.我将服务层理解为实现业务服务和公开给应用程序的层.由于Business不知道如何实现服务,因此可以委托给外部API.这样,企业仍然与一切脱钩. public class UserTrackingService : IUserTrackingService { private IUserRepository repo; // Injects an UserRepository to the service... public UserTrackingService(IUserRepository repository) { this.repo = repository; } public IEnumerable<User> GetDeadbetUsersWithTracking() { var users = this.repo.GetDeadbets(); this.Track(users); return users } public void Track(IEnumerable<User> source) { // This would use each ITrackable's (in this case each User) Identification to request some external API,get last known place and set to ITrackable's LastKnownPlace property... api.Track(source); } } 应用层 – 可能引用业务,红外/数据和服务层.在这里,您应该表达/定义应用程序可以执行的操作,而不是如何操作.应用程序只接收请求,对请求者进行身份验证,并保证他们有权执行所述操作.一切正常后,它会委托给服务/业务/下层.强烈建议使用DTO(或ViewModels)接收数据并将数据返回给外部世界.它可能从服务/业务/ infra层接收域数据,转换为DTO并返回.这可以解释为控制器. public class TrackedUserDTO { public string Name { get; set; } public string MainAddress { get; set; } public string LastKnownPlace { get; set; } public decimal TotalDebt { get; set; } public bool ShouldBeContacted { get; set; } } public class UserController : Controller { private IUserTrackingService service; private IUserRepository repository; // Injected - IoC public UserController(IUserTrackingService service,IUserRepository repository) { this.service = service; this.repository = repository; } public ActionResult Index() { return View(); } [Authorize(Roles="Manager,Admin",ErrorMessage="You aren't allowed do see this content...")] public ActionResult GetDeadbetUsersWithTracking() { IEnumerable<User> users = this.service.GetDeadbetUsersWithTracking(); IEnumerable<TrackedUserDTO> dtoUsers = Mapper.Map<IEnumerable<TrackedUserDTO>>(users); return View(dtoUsers); } 我强烈建议阅读这些: Creating Domain Services by Philip Brown Services in Domain-Driven Design by Jimmy Bogard 为什么不在业务层内使用DTO?避免Anemic Domain Model (by Martin Fowler) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 构建时验证所有ASPX,ASCX和HTML文件
- asp.net-mvc – 以编程方式隐藏全局菜单项的Razor代码?
- asp.net <%$...%>语法
- 调试 – 使用ASP.Net Core在VSCode中调试Typescript
- asp.net-mvc – 将模型传递给RedirectToAction()
- asp.net – WebBrowsable vs个性化Web部件
- asp.net – 如何将Enter键与aspx页面上的按钮相关联?
- asp.net-mvc-2 – 从.NET MVC 1迁移到MVC 2 RC
- asp.net-mvc – 当MVC路由触发时,在控制器中获取空参数值
- Razor 页面简化了 ASP.NET MVC 应用程序
- 如何缓存输出的action方法,返回图像到asp.net mv
- asp.net – System.EntryPointNotFoundException
- asp.net-mvc-3 – 禁用ASP.NET-MVC3中的unicode字
- asp.net – 如何通过ADO.NET运行我的.sql脚本文件
- 为什么这么多ASP.NET开发服务器实例?
- asp.net – 使用IHttpControllerSelector的Attri
- asp.net-mvc – 如何根据用户在ASP.NET MVC中的选
- asp.net-mvc-4 – ASP.Net MVC 4和WebSecurity –
- 防止ASP.Net中的重复回发(C#)
- asp.net-mvc – 使用RowAction更改Kendo MVC网格