ASP.NET MVC经典项目ProDinner项目解析(2)
上一篇文章介绍了整体架构,接下来我会就每一个类库层次做个逐次介绍
二、Core层解析
在Core中做了几件事情
第一层 Model
1、定义整个系统的实体类型,包括了每个实体的关联。
2、定义实体的公用字段(ID)和状态(IsDeteled),这两者非常简单,谁都能看得懂,作为范例,我觉得由此体现得更多的是一种思想。
我们在做表设计的时候,很多同学,对外键关联时,外键字段名和主表的主键名并不对应,我想对现今的数据库也好,ORM框架也好,或许不是什么大问题,但在做架构设计时估计就会遇到问题,或为此多付出代码。有同学用过DevExpress框架的话,这点会体现的更明显。
再者对于记录,状态、操作模块、操作时间等几乎每张表都会涉及的字段,最好每张表都能统一,这不是技术问题,是习惯和规范问题。
第二层 Repository
这层记录了所有的针对实体类的操作,也就是上一层Model的动作, 所以该层全部都是定义的接口,而针对每个Model的具体动作,在Service中去实现差异化
namespace Omu.ProDinner.Core.Repository { public interface IDelRepo<T> { IQueryable<T> Where(Expression<Func<T, bool>> predicate, bool showDeleted = false); IQueryable<T> GetAll(); void Restore(T o); } }
实体状态查询接口,三种操作,第一种根据每个实体继承的IsDeteled字段来筛选查询,由此我们可以联想到我们具体工作行业背景,如果你是做ERP的,各种单据的状态,审核、撤销、提交等我们都可以通过不同的接口不同的字段,然后不同的IRep来控制,于是一个复杂的ERP抽象单据状态控制层就出现了。如果你是做电子商务的,那么在订单提交的时候几种不同的状体,是否也可以考虑使用这种方式实现呢。
namespace Omu.ProDinner.Core.Repository { public interface IRepo<T> { T Get(int id); IQueryable<T> GetAll(); IQueryable<T> Where(Expression<Func<T, bool>> predicate, bool showDeleted = false); T Insert(T o); void Save(); void Delete(T o); void Restore(T o); } }
这层教之前一个接口,多了,删除、插入、和保存的操作。
namespace Omu.ProDinner.Core.Repository { public interface IUniRepo { T Insert<T>(T o) where T : Entity, new(); void Save(); T Get<T>(int id) where T : Entity; IEnumerable<T> GetAll<T>() where T : Entity; } }
这层接口,非常明显的限制了,操作的对象类型,必须是继承了Entity的类型,这样做的好处,个人认为是对于一些类的特殊限制,某些类型注定是不能拥有或者说他的增、删、改、查,是有限制的。
第三层 Security
这层就不再详细说了,引用了Asp.Net的身份验证模块,故也进行了相应的接口限制。
第四层 Service
该层接口详细定义了四个类的操作接口
ICrudService继承了上层接口的抽象接口
IMealService类继承了 ICrudService 同时,规定了图片保存的接口
IUserService继承了ICrudService,规定了用户验证的接口
ProDinnerException规定了系统自定义的抛错机制。
第二层和第四层之间的这么做的理由以及对后续模块设计的影响,有无其他的联系和影响,我暂时只看出了这些,对源代码的解析,其他同学还有无其他的看法,还请能分享出来,第一篇就说了,我只是在抛砖引玉。希望共同进步。