前言 大家好,我依舊是你們的老朋友Rector,很高興又在周五的時候準時和大家見面。 Rector的系列文章【一步一步創建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](七)》