ASP.NET MVC经典项目ProDinner项目解析(5)
五、Service层解析
该层在功用上看其名称我们应该大致就能知道它是做什么的,Service---提供服务的,类似我们三层架构中的服务提供层或业务逻辑层.
由于整个项目用到了,Castle的依赖倒转,所以这层在实现业务逻辑时,运用的手法也是比较抽象的,在和具体的业务相关联的时候,并没有使用具体的类型,而是使用泛型T,Expression<Func<T, bool>>来解决耦合问题.
功能类划分
CrudService.cs--实体业务逻辑实现service
FileManagerService.cs---文件上传、图片上传service
MealService.cs---图片设置具体到项目中,为设置每个食物的图片而单独的一个service
UserService.cs---用户信息操作业务实现层
首先,CrudService类,看看类名:
public class CrudService<T> : ICrudService<T> where T : DelEntity, new()
做了泛型类,不仅类本身做了类型限制,连同其继承的接口类型都做了类型限制。Public class CrudService<T>,使用泛型类的一个好处就是,类中定义的所有操作并不针对一个特定的Model实体,而是根据在调用实例化的时候传过来的类型而定,换句话说,该类中定义的所有方法适用T类型,所以普通的增删改查都定义在了这个类当中。这和我们很多同学在写业务逻辑的时候,针对一个Model去写一个业务实现,就如同一个屌丝和一个高富帅的距离。
ICrudService<T> where T,这句话翻译成普通话就是,要求类型T实现ICrudService,CrudService进行了显式约束继承,换句话说,T具备这些接口定义的所有方法。
DelEntity继承实现了Entity一个具体的Model,这个Model只有一ID,说到底也是最公用的东西。
New()该类必须实例化使用,官方正规说辞,必须具备Public构造函数。
再次:FileManagerService类
public class FileManagerService : IFileManagerService
比较常规,实现了前面定义的接口
public void DeleteImages(string root, string filename)
public void MakeImages(string root, string filename, int x, int y, int w, int h)
public string SaveTempJpeg(string root, Stream inputStream, out int w, out int h)
这个方法实体,有兴趣的同学可以看看,这个很常用,方法体实现了删除大中小三张图片,做电商的同学应该会经常遇到这样的问题,一张图片上传后,会生产不同规格尺寸的图片,这只是一个实例开源项目,这当中透露出来的开放封闭原则和规范的代码方式,我觉得远不是我写这篇文章和看下代码能学习完的,我想对于很多同学甚至我自己,有时候在做项目的时候,遇到上传文件或者图片,就一个类或者一个函数搞定了,某年某月的某一天客户或者领导要求改一个东西,涉及到这个类的时候,推到重写。当然这个项目还用到了Omu项目,源代码在这个项目重并没有公开出来,对于上传图片其实是借用了Omu类的Imager基类,大致可以猜想出代码是如何实现的,以上三个方法实现了图片上传和设置的开放操作,对于公用的上传到具体文件夹和删除文件的操作,应该是封装起来了。
这层代码开始和具体业务逻辑相关联了,并开始涉及到了Omu的使用,包括后面的View层都用使用到了Omu的自定义控件,尤其是其实现的MVC Ajax控件,有兴趣的同学可以试用下,集成了Jquery的无刷新无js代码,正式版应该是需要收费的:
http://awesome.codeplex.com/discussions/428678