前言

大家好,我依旧是你们的老朋友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](七)

一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](七)的更多相关文章

  1. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](一)

    前言 大家好,我是Rector 从今天开始,Rector将为大家推出一个关于创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar]的文章系列, ...

  2. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](五)

    前言 Hi,大家好,我是Rector 时间飞逝,一个星期又过去了,今天还是星期五,Rector在图享网继续跟大家分享系列文本:一步一步创建ASP.NET MVC5程序[Repository+Autof ...

  3. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](四)

    前言 上一篇<一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](三)>,我们完成了: * 引用SqlSugar * ...

  4. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](三)

    前言 上一篇<一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](二)>我们通过如下操作: 创建实体及工具类 创建Re ...

  5. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](二)

    前言: 在本系列第一篇<一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](一)>中,我为大家介绍了搭建空白解决方案以 ...

  6. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](六)

    前言 大家好,我是Rector 又是星期五,很兴奋,很高兴,很high...啦啦啦... Rector在图享网又和大家见面啦!!!上一篇<一步一步创建ASP.NET MVC5程序[Reposit ...

  7. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](八)

    前言 Hi, 大家好,还是星期五,还是Rector,又在图享网准时和大家见面了. 今天给大家带来系列教程<一步一步创建ASP.NET MVC5程序[Repository+Autofac+Auto ...

  8. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](九)

    前言 童鞋们,大家好 我是专注.NET开发者社区建设的实践者Rector. 首先,为自己间隔了两个星期五再更新本系列文章找个不充分的理由:Rector最近工作,家庭的各种事务所致,希望大家谅解. 本文 ...

  9. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](十)

    前言 朋友们, 大家好,我还是Rector,写ASP.NET MVC 5系列文章[一步一步创建ASP.NET MVC5程序Repository+Autofac+Automapper+SqlSugar] ...

随机推荐

  1. day9集合以及这段时间的总结 未完待续

    随笔: # 可变类型:# 列表(可以存放多个值,可以按索引取值,是有序的),# 字典(字典里面是KEY:VALUE类型,key必须是不可变类型,不能按索引取值 因为它们是无序的,按KEY取值),# 集 ...

  2. 部署Tomcat服务时,解决Cannot invoke Tomcat Manager 异常

    最近,在使用Jenkins对工程一键部署的时候,出现调用Tomcat Manager 异常,对其解决方案特记于次. 异常信息 可能存在的异常:(1)Cannot invoke Tomcat manag ...

  3. Nodejs的运行原理-调用篇

    前言 之前做过Nodejs的架构篇, 有很多朋友留言给我,说没看懂里面的例子,这里我会重新梳理一下,再以http server为例,来解析Nodejs从前端到libuv的调用过程. 正文 回忆a. N ...

  4. AIO5凭证性质设置接收下/上差(%),但是订单操作不起效。

    问题: AIO5凭证性质设置接收下/上差(%),但是订单操作不起效. 例如: 现在采购订单下了200个,我想限制收货只能收两百以内. 在在线帮助上看到有接收下/上差(%)字段可以进行限制,但是在凭证性 ...

  5. Spark入门,概述,部署,以及学习(Spark是一种快速、通用、可扩展的大数据分析引擎)

    1:Spark的官方网址:http://spark.apache.org/ Spark生态系统已经发展成为一个包含多个子项目的集合,其中包含SparkSQL.Spark Streaming.Graph ...

  6. Box布局

    import sys from PyQt4 import QtCore, QtGui class MainWindow(QtGui.QWidget): def __init__(self, paren ...

  7. [转载]使用awk进行数字计算,保留指定位小数

    对于在Shell中进行数字的计算,其实方法有很多,但是常用的方法都有其弱点: 1.bc bc应该是最常用的Linux中计算器了,简单方便,支持浮点. [wangdong@centos715-node1 ...

  8. 找出生成json中的error_code,并加以处理

    需求: 前段时间调用了百度AI的分词接口,因为不完全支持并发,一些调用产生了错误,混在json内部. 现在需要将未调用成功的内容重新调用一遍. 思考过程: 方法一: 开始想到的是调用的过程当中,如果报 ...

  9. Codeforces #448 Div2 E

    #448 Div2 E 题意 给出一个数组,有两种类型操作: 选定不相交的两个区间,分别随机挑选一个数,交换位置. 查询区间和的期望. 分析 线段树区间更新区间求和. 既然是涉及到两个区间,那么对于第 ...

  10. Python3——让我们像孩子一样的去看书

    用tkinter来画高级图形 让我们一起创造一个按钮吧!"按住我:0  :" 那我们先做一个小例子,让我们第一眼先认识到这个它(tkinter)吧! 输入以下代码: from tk ...