zoukankan      html  css  js  c++  java
  • ASP.NET MVC系列 框架搭建(三)之服务层的搭建

    邯郸学步

    吾虽是一不知名的菜鸟,但,吾亦有一个从后台程序员成为一名小小架构师梦想,深知架构师不是想想就成的。

    吾已工作过一阵子,吾妄想在真正毕业之后工作一年左右就能拿到那个数ten thousand的工资。勿喷!

    我们成长的环境不同,也许有人一手栽培,也许只能一个人默默奋斗。不论怎样,

    我们要先学会造轮子,但我只会造4个高质量的轮子。让我的车子稳健地跑起来!

    深知实现这些规划,我必须要付出常人难以付出的努力!

    这些东西,会了就是不值一提的东西,不会就是高大上。

    更希望能给读者带来一些新的认识及知识。

    各位大神,请点支持一下小弟。最后我会为看官上传源码+数据库。

    陆续更新。更新到你会为止!!

    上篇衔接

    篇二中通过一个工厂造出一个线程内唯一的继承IDBContact的DBContact。

    并通过一个另一个工厂造出一个线程内唯一的继承ObjextContext的ModelContainer写成DBContact的属性。

    并把上下文的Savechange()封装到DBContact里面

    让执行SQL在服务层中控制逻辑。当然去掉了仓储层的ModelContainer的Savechange()

    并把每个仓储写成对应的属性。  

    目的:就是业务逻辑(这里叫服务层)只通过这个类来进行访问数据层(这里叫仓储层)。

    ①DBContact.cs

    using LKBS.CommunicationPlatform.IDAL;
    using System.Data.Objects;//上下文的命名空间
    using LKBS.CommunicationPlatform.Factory;
    using System.Data.SqlClient;
    
    namespace LKBS.CommunicationPlatform.DAL
    {
     public class DBContact : IDBContact
     {
    
      public ObjectContext currentEFContext { get; set; }
      ISingleEFCntextFactory singleEFCntextFactory = new SingleEFCntextFactory();//SingleEFCntextFactory做到单一DBContact
      public DBContact()
      {
       currentEFContext = singleEFCntextFactory.GetCurrentEFContext();//
      }
    
      public int excuteSQL(string cmdText, SqlParameter[] parammeters)
      {
       return currentEFContext.ExecuteStoreCommand(cmdText, parammeters);
      }
      //在仓储层BaseRespository就不用savechang了,让其在服务层控制提交数据库
      //放在服务层这就是业务逻辑,根据业务逻辑层的一个场景,简单说一个方法中可能用到多个表。最后执行保存。做到和数据库交互一次
      public int saveChange()
      {
       return this.currentEFContext.SaveChanges();
      }
      public IUserInforRespository userinforResponsity { get; set; }
     }
    }

    ②IDBContact.cs

    using System.Data.Objects;
    using System.Data.SqlClient;//上下文在的空间
    
    namespace LKBS.CommunicationPlatform.IDAL
    {
      public interface IDBContact
       {
        //接口中的属性要{}
        ObjectContext currentEFContext { get; set; }
        int excuteSQL(string cmdText, SqlParameter[] parammeters);
         int saveChange();
        IUserInforRespository userinforResponsity { get; set; }
        //...多个其他表的仓储,在T4模板中加OK
       }
    }

    重点查看

    ⑥BaseService.cs中的获得仓储层的实例的逻辑。

    为了获得实例我们在我们在BaseService中写一个获得实例的抽象方法,

    为了必须在自类继承并保证在子类④UserInforService必须实现此方法,我们把BaseService写成了一个抽象类。必须写成!

    什么时候执行呢?当子类实例化的时候,会调用基类构造方法。所以我们在基类的构造函数中调用这个获得实例的抽象方法。

    ok,说了这么一大通,其实就是对抽象类和抽象方法的实践运用。还有实践运用子类实例化会调用基类构造方法这点!

    最后,这一大通就是一个循环。理解了就会这样觉得。这种方式实现了 子类掉基类 基类调子类循环

    服务层的创建

    在这个层搭建的过程中,我漏洞百出,木有public或者木有程序集引用或者木有using,接口对象掉不出实例接口中已经具备的方法,老是警告。

    不能直接赋值非静态变量或者属性或者方法等,最终还是都解决了。最终的程序没有一个警告。全部通过。

    框架搭的差不多了。数据库其实我已经建好,只是没发上来。

    下篇我就要开始搭前台了。

    这个过程中,就是一个成长的过程,我要记录下来。以后少出这样的错。即使出错,我会很快的改正。

    ③IUserInforService.cs

    using LKBS.CommunicationPlatform.Model;
    
    namespace LKBS.CommunicationPlatform.IBll
    {
     public interface IUserInforService : IBaseService<UserInfor>
      {
    
      }
    }

    ④UserInforService.cs

    using LKBS.CommunicationPlatform.IBll;
    using LKBS.CommunicationPlatform.Model;
    using LKBS.CommunicationPlatform.IDAL;
    using LKBS.CommunicationPlatform.DAL;
    
    
    namespace LKBS.CommunicationPlatform.Bll
    {
      public class UserInforService:BaseService<UserInfor>, IUserInforService
       {
         public override void setCurrentRespository()
         {//此时点不出父类的dbContact 因为这个字段没有public
           this.currentRespository = this.dbContact.userinforResponsity;
         }
       }
    }

    ⑤IBaseService.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace LKBS.CommunicationPlatform.IBll
    {
     public interface IBaseService<T>
      {
      bool AddEntity(T entity);
      bool DeleteEntity(T entity);
      bool UpdateEntity(T entity);
      T SelectOneEntity(Func<T, bool> wherelamda);
      IQueryable<T> SelectAllEntityList(Func<T, bool> wherelamda);
      IQueryable<T> SelectPageEntityList<S>(Func<T, S> orderLamda, Func<T, bool> whereLamda, int pageIndex, int pageSize, bool isAsc, out int rowcount);
      }
    }

    ⑥BaseService.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using LKBS.CommunicationPlatform.Model;
    using LKBS.CommunicationPlatform.IDAL;
    using LKBS.CommunicationPlatform.DAL;
    using LKBS.CommunicationPlatform.Factory;
    using System.Data.Entity;
    using System.Runtime.Remoting.Messaging;
    
    
    namespace LKBS.CommunicationPlatform.Bll
    {
     public abstract class BaseService<T> where T : class,new()
     {
      //未添加程序集:using;类木有public 都能找不能这个类
      ISingleDBContactFactory singleDBContactFactory = new SingleDBContactFactory();
      public IDBContact dbContact;
      public BaseService()
      {
       dbContact = singleDBContactFactory.CreateDBCotactUseEF();
       //获取当前的仓储实例   重点逻辑!!!!! 将此类写成抽象类,子类必须实现。
       //子类实例化时候,调用基类狗狗函数 ,构造函数执行基类虚方法,基类虚方法有调用子类实现的方法。然后继续执行基类下面代码
       //这个逻辑才是真正对面向对象的理解和抽象类的使用的精髓使用。!!
       setCurrentRespository();
      }
      public abstract void setCurrentRespository();
      //错误    2    类型“T”必须是引用类型才能用作泛型类型或方法
      //忘记在类中加上where T:class,new()
      public IBaseRespository<T> currentRespository;
    
      public bool AddEntity(T entity)
      {
       currentRespository.AddEntity(entity);
       if (dbContact.saveChange() > 0)  //找不到saveChange,接口中没有此方法,但子类有0.0
       {
        return true;
       }
       else
       {
        return false;
       }
       
      }
    
      public bool DeleteEntity(T entity)
      {
    
       currentRespository.DeleteEntity(entity);
       
       if (dbContact.saveChange()>0)
       {
        return true;
       }
       else
       {
        return false;
       }
     
      }
    
      public bool UpdateEntity(T entity)
      {
       currentRespository.UpdateEntity(entity);
       if (dbContact.saveChange()>0)
       {
        return true;
       }
       else
       {
        return false;
       }
      
      }
      /// <summary>
      /// 单个实体
      /// </summary>
      /// <param name="wherelamda"></param>
      /// <returns></returns>
      public T SelectOneEntity(Func<T, bool> wherelamda)
      {
       return currentRespository.SelectOneEntity(wherelamda);
      }
      /// <summary>
      /// 查询 整张表或者多个实体 
      /// </summary>
      /// <returns></returns>
      public IQueryable<T> SelectAllEntityList(Func<T, bool> wherelamda)
      {
       return currentRespository.SelectAllEntityList(wherelamda);
      }
      int rowcount = 0;
      //泛型方法 <S>就是约束参数的类型,传什么参数,“自动识别”<S>. 定义需要<S>,调用该方法可以省略 :因为传的参数就已确定<S>的类型
      public IQueryable<T> SelectPageEntityList<S>(Func<T, S> orderLamda, Func<T, bool> whereLamda, int pageIndex, int pageSize, bool isAsc, out int rowcount)
      {//非页数pageCount,是总行数
       return currentRespository.SelectPageEntityList<S>(orderLamda,whereLamda, pageIndex, pageSize, isAsc, out rowcount);
       }
      }
    
     }

    下篇衔接

    数据库我已经建好,当然还有需要完善数据库的地方,毕竟需求的分析是要变化的。

    最后我会发上来,现在不发,因为架构用不到数据库。最后看官亲自动动手调试的时候,我自会奉献上。这算是小小的“干货”吧。自勉

    T4模板的使用,对数据库表的生成,完善和数据库表的全部映射。

    下篇我就开始搭前台了。这个估计要几天才能搞定。

     

  • 相关阅读:
    MySql自定义函数-关于保留小数位的特殊需求
    MySQL-时区导致的时间前后端不一致
    [计算机基础] 汇编学习(3)
    [计算机基础] 汇编学习(2)
    [计算机基础] 汇编学习(1)
    [安全] metasploit(2)
    [安全] Kali Linux安装TheFatRat
    [安全] metasploit(1)
    [安全] tcpdump使用
    [安全] netcat和socat的使用
  • 原文地址:https://www.cnblogs.com/leee/p/4516615.html
Copyright © 2011-2022 走看看