一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](七)
前言
大家好,我依旧是你们的老朋友Rector,很高兴又在周五的时候准时和大家见面。
Rector的系列文章【一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar]】从写作以来,已经出了六期了,其中受到了很多朋友的喜欢,在此非常感谢大家对Rector的支持,也希望Rector的文章可以帮助大家(特别是才接触或者是对.NET/C#高级编程比较薄弱的朋友们)在.NET/C#的开发之旅中更快地提升自己的开发技巧和经验。
上一篇《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](六)》我们对TsBlog应用程序的仓储层进行了一次重大的重构,即:使用泛型仓储将通用的数据库操作进行了封装,让我们在创建仓储层接口和实现的时候能精简重复的代码,今天要给大家分享的是对服务层的泛型封装和重构,实现原理大致与仓储层相似。
本文知识要点
- 泛型服务层的封装与重构
重构服务层
提取泛型服务基类
打开项目【TsBlog.Services】,创建 服务层通用接口类 IService.cs,在其中创建服务层通用的接口方法,如下:
using System; using System.Collections.Generic; using System.Linq.Expressions; namespace TsBlog.Services { /// <summary> /// 服务接口 /// </summary> /// <typeparam name="T"></typeparam> public interface IService<T> { /// <summary> /// 根据主值查询单条数据 /// </summary> /// <param name="pkValue">主键值</param> /// <returns>泛型实体</returns> T FindById(object pkValue); /// <summary> /// 查询所有数据(无分页,请慎用) /// </summary> /// <returns></returns> IEnumerable<T> FindAll(); /// <summary> /// 根据条件查询数据 /// </summary> /// <param name="predicate">条件表达式树</param> /// <param name="orderBy">排序</param> /// <returns>泛型实体集合</returns> IEnumerable<T> FindListByClause(Expression<Func<T, bool>> predicate, string orderBy); /// <summary> /// 根据条件查询数据 /// </summary> /// <param name="predicate">条件表达式树</param> /// <returns></returns> T FindByClause(Expression<Func<T, bool>> predicate); /// <summary> /// 写入实体数据 /// </summary> /// <param name="entity">实体类</param> /// <returns></returns> long Insert(T entity); /// <summary> /// 更新实体数据 /// </summary> /// <param name="entity"></param> /// <returns></returns> bool Update(T entity); /// <summary> /// 删除数据 /// </summary> /// <param name="entity">实体类</param> /// <returns></returns> bool Delete(T entity); /// <summary> /// 删除数据 /// </summary> /// <param name="where">过滤条件</param> /// <returns></returns> bool Delete(Expression<Func<T, bool>> @where); /// <summary> /// 删除指定ID的数据 /// </summary> /// <param name="id"></param> /// <returns></returns> bool DeleteById(object id); /// <summary> /// 删除指定ID集合的数据(批量删除) /// </summary> /// <param name="ids"></param> /// <returns></returns> bool DeleteByIds(object[] ids); } }
再创建 泛型基类 GenericService.cs,在其中创建服务层通用的方法,如下:
using System; using System.Collections.Generic; using System.Linq.Expressions; using TsBlog.Repositories; namespace TsBlog.Services { public abstract class GenericService<T> : IService<T>, IDependency where T : class, new() { private readonly IRepository<T> _repository; protected GenericService(IRepository<T> repository) { _repository = repository; } /// <summary> /// 根据主值查询单条数据 /// </summary> /// <param name="pkValue">主键值</param> /// <returns>泛型实体</returns> public T FindById(object pkValue) { return _repository.FindById(pkValue); } /// <summary> /// 查询所有数据(无分页,请慎用) /// </summary> /// <returns></returns> public IEnumerable<T> FindAll() { return _repository.FindAll(); } /// <summary> /// 根据条件查询数据 /// </summary> /// <param name="predicate">条件表达式树</param> /// <param name="orderBy">排序</param> /// <returns>泛型实体集合</returns> public IEnumerable<T> FindListByClause(Expression<Func<T, bool>> predicate, string orderBy) { return _repository.FindListByClause(predicate, orderBy); } /// <summary> /// 根据条件查询数据 /// </summary> /// <param name="predicate">条件表达式树</param> /// <returns></returns> public T FindByClause(Expression<Func<T, bool>> predicate) { return _repository.FindByClause(predicate); } /// <summary> /// 写入实体数据 /// </summary> /// <param name="entity">实体类</param> /// <returns></returns> public long Insert(T entity) { return _repository.Insert(entity); } /// <summary> /// 更新实体数据 /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool Update(T entity) { return _repository.Update(entity); } /// <summary> /// 删除数据 /// </summary> /// <param name="entity">实体类</param> /// <returns></returns> public bool Delete(T entity) { return _repository.Delete(entity); } /// <summary> /// 删除数据 /// </summary> /// <param name="where">过滤条件</param> /// <returns></returns> public bool Delete(Expression<Func<T, bool>> @where) { return _repository.Delete(@where); } /// <summary> /// 删除指定ID的数据 /// </summary> /// <param name="id"></param> /// <returns></returns> public bool DeleteById(object id) { return _repository.DeleteById(id); } /// <summary> /// 删除指定ID集合的数据(批量删除) /// </summary> /// <param name="ids"></param> /// <returns></returns> public bool DeleteByIds(object[] ids) { return _repository.DeleteByIds(ids); } } }
精简并修改 IPostService.cs:
using TsBlog.Domain.Entities; using TsBlog.Repositories; namespace TsBlog.Services { public interface IPostService : IDependency, IService<Post> { } }
再精简并修改 PostService.cs:
using TsBlog.Domain.Entities; using TsBlog.Repositories; namespace TsBlog.Services { public class PostService : GenericService<Post>, IPostService { private readonly IPostRepository _repository; public PostService(IPostRepository repository) : base(repository) { _repository = repository; } } }
重新编译并按F5运行 【TsBlog.Frontend】Web应用程序,你会看到如下的错误提示:
这是为什么呢?是因为我们之前写好的 PostRepository.cs类中没有继承IPostRepository接口,但我们在 PostService.cs 类中使用了非泛型的 IPostRepository接口,所以在 PostRepository.cs 类中添加 IPostRepository 的接口,此时的 PostRepository.cs :
using TsBlog.Domain.Entities; namespace TsBlog.Repositories { /// <summary> /// POST表的数据库操作类 /// </summary> public class PostRepository : GenericRepository<Post>, IPostRepository { } }
最终的 Global.asax.cs :
using Autofac; using Autofac.Features.ResolveAnything; using Autofac.Integration.Mvc; using System; using System.Linq; using System.Web.Mvc; using System.Web.Routing; using TsBlog.AutoMapperConfig; using TsBlog.Repositories; namespace TsBlog.Frontend { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); //BundleConfig.RegisterBundles(BundleTable.Bundles); AutofacRegister(); AutoMapperRegister(); } private void AutofacRegister() { var builder = new ContainerBuilder(); //注册MvcApplication程序集中所有的控制器 builder.RegisterControllers(typeof(MvcApplication).Assembly); //注册仓储层服务 //builder.RegisterType<PostRepository>().As<IPostRepository>(); //注册基于接口约束的实体 var assembly = AppDomain.CurrentDomain.GetAssemblies(); builder.RegisterAssemblyTypes(assembly) .Where( t => t.GetInterfaces() .Any(i => i.IsAssignableFrom(typeof(IDependency))) ) .AsImplementedInterfaces() .InstancePerDependency(); //builder.RegisterGeneric(typeof(GenericRepository<>)) // .As(typeof(IRepository<>)); //builder.RegisterGeneric(typeof(GenericService<>)) // .As(typeof(IService<>)); //builder.RegisterGeneric(typeof(GenericRepository<>)); //builder.RegisterGeneric(typeof(GenericService<>)); //注册服务层服务 //builder.RegisterType<PostService>().As<IPostService>(); //注册过滤器 builder.RegisterFilterProvider(); builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); var container = builder.Build(); //设置依赖注入解析器 DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } /// <summary> /// AutoMapper的配置初始化 /// </summary> private void AutoMapperRegister() { new AutoMapperStartupTask().Execute(); } } }
再次按F5运行,打开页面[http://localhost:54739/home/post ],页面又回来了,哈哈。。。
本文的源码托管地址:https://github.com/lampo1024/TsBlog/releases/tag/v1.7.1
本文学习到此结束,本系列未完待续,我们下期再见……
如果你喜欢Rector的本系列文章,请为我点个大大的赞。
如果遇到问题,欢迎加入图享网官方QQ群:483350228
本文来源 图享网 《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](七)》