一步一步創建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應用程序,你會看到如下的錯誤提示:

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](七)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM