[聚合文章] 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](七)

ASP.NET 2018-01-29 16 阅读

前言

大家好,我依旧是你们的老朋友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应用程序,你会看到如下的错误提示:

create-aspnet-mvc-5-web-application-repository-autofac-automapper-sqlsugar-step-by-step-07-01.png

这是为什么呢?是因为我们之前写好的 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](七)

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。