• ASP.NET MVC系列 框架搭建(二)之仓储层的优化


    大神勿喷,小神默默学。

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

    最后上传源码。希望能给读者带来一些新的认识及知识。

    还没上过头条。。各位大神,请点支持一下小弟。

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

    我不是话唠,我只把重点点出来,细枝末节的不懂的可以留言探讨。这个系列的最后,我会再统一的把大家的问题,列在一篇新的Blog。工作需要规划,写博客也是如此。

    需求

    ①请保持EF上下文的线程唯一。防止脏临时数据的出现

    ②请对程序扩展性做好设计。以后ef框架可能改为Spring框架

    ③服务层调用仓储层时。DBContext为统一入口

        ③.1 方便程序员开发,提供统一入口。把ef封装到此入口里面。

        ③.2防止脏临时数据的出现,“也”请保持这个入口的线程内唯一。

        ③.3要这个统一入口去除服务层和仓储层的耦合

    思路

    ①把ef放进CallContext内。键值对形式存放。

    ②面向接口的思想

     新建一个工厂接口+工厂。用一个“工厂方法”模式,非“简单工厂”,也非“抽象工厂”设计模式。如果您对工厂的几个设计模式不了解,请参考我写过的设计模式一篇blog。

    ③ ③.1新建一个类,命名DBContact里面的一个属性类型为ObjectContext,因为上下文继承ObjectContext,继而“点”多个仓储。 

        ③.2放进CallContext内。键值对存储。

        ③.3新建一个IDBContact接口,让DBContact继承。用一个工厂继承一个接口工厂创建。“工厂方法”设计模式

    思想

    面向接口+工厂模式+线程唯一 2个抽象方法工厂作用:线程唯一+扩展性(面向接口)

    详情代码

    ISingleEFCntextFactory.cs

    using System.Data.Objects;
    
    namespace LKBS.CommunicationPlatform.IDAL
    {
     public interface ISingleEFCntextFactory
     {//no public
     ObjectContext GetCurrentEFContext();
     }
    }

    SingleEFCntextFactory.cs

    using LKBS.CommunicationPlatform.IDAL;
    using System.Data.Objects;//添加引用 System.Data.Entity
    using System.Runtime.Remoting.Messaging;
    using LKBS.CommunicationPlatform.Model;
    
    
    namespace LKBS.CommunicationPlatform.Factory
    {
     public class SingleEFCntextFactory : ISingleEFCntextFactory
     {
      public ObjectContext GetCurrentEFContext()
      {
       //把上下文(基类)放在一个线程内。让一次请求(一个ACTION)可能执行CRUD中的几步,公用一个上下文.
       ObjectContext callEFContext = (ObjectContext)CallContext.GetData("efContext");//线程槽 存放“键值对”
       //先读后写。没有就new一个上下文
       if (callEFContext == null)
       {
        callEFContext = new ModelContainer();
       }
       CallContext.SetData("efContext", callEFContext);
       return callEFContext;
      }
     }
    }

    BaseRespository.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using System.Data.Entity;
    using LKBS.CommunicationPlatform.Model;
    using LKBS.CommunicationPlatform.IDAL;
    using System.Data;
    using LKBS.CommunicationPlatform.Factory;
    using System.Data.Objects;
    
    
    namespace LKBS.CommunicationPlatform.DAL
    {
       public class BaseRespository<T> where T : class,new()
       {
          ISingleEFCntextFactory singleEFFactory = new SingleEFCntextFactory();
          //中间加一个工厂,这里“去除”ef和具体仓储的耦合。可以更换ef。而Respositiry db不用变
          ObjectContext db;//如果没赋值,那就是赋值的问题。找对应赋值的工厂 或者工厂还没编译
          public BaseRespository()
          {
             ObjectContext db = singleEFFactory.GetCurrentEFContext();
          }
    
          //ModelContainer db = efFactory.GetCurrentEFContext();
          //字段初始值无法引用非静态字段、方法或属性.
          //那我们在构造方法内赋值
    ....CRUD
        }
    }

    为方便业务逻辑层调用,建立统一入口。

    IDBContact.cs

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

    DBContact.cs

    using LKBS.CommunicationPlatform.IDAL;
    using System.Data.Objects;//上下文的命名空间
    using LKBS.CommunicationPlatform.Factory;
    
    namespace LKBS.CommunicationPlatform.DAL
    {
     public class DBContact : IDBContact
     {
      public ObjectContext currentEFContext { get; set; }
      ISingleEFCntextFactory singleEFCntextFactory = new SingleEFCntextFactory();//SingleEFCntextFactory做到单一上下文
      public DBContact()
      {
       currentEFContext = singleEFCntextFactory.GetCurrentEFContext();//
      }
      public IUserInforRespository userinforResponsity { get; set; }
     }
    }

    ISingleDBContactFactory.cs

    namespace LKBS.CommunicationPlatform.IDAL
    {
      public interface ISingleDBContactFactory
       {
          IDBContact CreateDBCotactUseEF();
       }
    }

    SingleDBContactFactory.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using LKBS.CommunicationPlatform.IDAL;
    using System.Data.Objects;
    using System.Runtime.Remoting.Messaging;
    using LKBS.CommunicationPlatform.DAL;
    
    
    namespace LKBS.CommunicationPlatform.Factory
    {
       //继承接口①接口要编译过,②引入接口所用的程序集+ using
       class SingleDBContactFactory : ISingleDBContactFactory
       {
          public IDBContact CreateDBCotactUseEF()
          {
             //ObjectContext currentEFContext = new ObjectContext("currentEFContext");
             //return currentEFContext;
             IDBContact dbCotact = (DBContact)CallContext.GetData("currentDBContact");
             if (dbCotact==null)
             {
                dbCotact = new DBContact();
             }
             CallContext.SetData("currentDBContact", dbCotact);
             return dbCotact;
    
          }
       }
    }

      

  • 相关阅读:
    UDP:用户数据报协议(User Datagram Protocol)
    线程池的使用
    SQL Server表和模式空间使用情况http://www.51myit.com/thread2466911.html
    bytetobmp and bmptobyte(Image)
    c# TCP例子转载
    POJ 4047Garden
    NYOJ 102 次方求模
    Sum
    POJ 1094 Sorting It All Out(经典拓扑,唯一排序)
    POJ 2387 Til the Cows Come Home(Dijkstra)
  • 原文地址:https://www.cnblogs.com/leee/p/4513498.html
Copyright © 2020-2023  润新知