DDD~WCF做中间件,实现多个项目的缓存共享

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
性能测试 PTS,5000VUM额度
云原生网关 MSE Higress,422元/月
简介:

事情是这样的,前台网站有些数据不希望每次都从数据库里读,所以,应该做个缓存,而引起缓存更新的入口来自网站的后台管理,而前台和后台被部署在不同的网站中,这时缓存的更新就成了问题,前台的缓存与后台的操作不能联系到一起,为了解决这个问题,我引入了WCF作为中间件,所以与数据库的操作,读,写都来自一个入口,那就是WCF,WCF用户告诉你是否从缓存取数据,所有缓存的数据也缓存在WCF中,OK,想法不错,下面来说一下具体的实现步骤。

一 首先看一下结构图:

注意看我的结构图,前台aop_cache和后台aop_cache_background项目都引用aop_cache_webservice项目,而它们没有对数据层aop_cache_data的引用,这个aop_cache_webservice是一个WCF项目,主要实现与数据层的通讯工作,当然也可以与BLL业务层通讯,这个架构主要是讲如何实现前后台共享缓存,而并非讲架构,所以重要不再架构,而在实现共享缓存。

二 WCF层实现所需要的DLL,主要是unity,cache,interception,log4net等,如图:

三 对于unity,wcf,cache的调用上,我进行了二次封装,如图:

四 看了这些,我们再来看一下,WEB层调用WCF层的代码片断:

        public ActionResult Index()
        {
            //  通过WCF获取远程数据,不走缓存, 走config中的<system.serviceModel>
            using (ServiceProxy<IService1> proxy = new ServiceProxy<IService1>())
            {
                return View(proxy.Channel.GetClassroom_Info());
            }
        }

web层的配置文件包含了对WCF的调用

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="ServiceProxyBinding" sendTimeout="00:10:00" receiveTimeout="00:10:00" closeTimeout="00:10:00"></binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint name="IService1" address="http://www.aop.com/Service1.svc" contract="aop_cache_WebService.IService1" binding="basicHttpBinding" bindingConfiguration="ServiceProxyBinding" />
    </client>
  </system.serviceModel>

五 WCF层调用DAL层的代码,使用unity来做方法拦截与依赖注入,将cache功能注入到指定方法中

        IClassroom_InfoRepository _iClassroom_InfoRepository = ServiceLocator.Instance.GetService<IClassroom_InfoRepository>();
        public void InsertClassroom_Info(Classroom_Info entity)
        {
            _iClassroom_InfoRepository.InsertClassroom_InfoData(entity);
        }

        public List<Classroom_Info> GetClassroom_Info()
        {
            return _iClassroom_InfoRepository.GetClassroom_InfoData();
        }

六 对于WCF的配置文件,我们要重要看一下,它包含了数据库连接串的配置和unity的配置

  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <connectionStrings>
    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-aop_cache-20131030092430;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-aop_cache-20131030092430.mdf" />
    <add name="TsingDa_NewLearningBarEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=TsingDa_NewLearningBar;user id=sa;password=zzl123;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

  <!--BEGIN: Unity-->
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
    <container>
      <extension type="Interception" />
      <register type="Project.Caching.ICacheProvider,  Project.Caching" mapTo="Project.Caching.EntLibCacheProvider,  Project.Caching" />
      <!--对WCF的访问进行的注入与缓存和异常的拦截-->
      <register type="aop_cache_Data.IClassroom_InfoRepository, aop_cache_Data" mapTo="aop_cache_Data.Classroom_InfoRepository, aop_cache_Data">
        <interceptor type="InterfaceInterceptor" />
        <interceptionBehavior type="Project.InterceptionBehaviors.CachingBehavior, Project.InterceptionBehaviors" />
      </register>
    </container>
  </unity>
  <!--END: Unity-->
  <!--BEGIN: Caching-->
  <cachingConfiguration defaultCacheManager="ByteartRetailCacheManager">
    <cacheManagers>
      <add name="ByteartRetailCacheManager" type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" expirationPollFrequencyInSeconds="600" maximumElementsInCacheBeforeScavenging="1000" numberToRemoveWhenScavenging="10" backingStoreName="NullBackingStore" />
      <!--
          expirationPollFrequencyInSeconds:过期时间(seconds)
          maximumElementsInCacheBeforeScavenging:缓冲中的最大元素数量
          numberToRemoveWhenScavenging:一次移除的数量
      -->
    </cacheManagers>
    <backingStores>
      <add type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="NullBackingStore" />
    </backingStores>
  </cachingConfiguration>
  <!--END: Caching-->

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Practices.Unity" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Practices.Unity.Interception" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
<system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Warning" propagateActivity="true">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="d:\wcf.svclog" />
    </sharedListeners>
  </system.diagnostics>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

七 DAL层的实现,由接口和实现两部分组成,接口的方法上规定了是否要进行cache操作

   public interface IClassroom_InfoRepository
    {
        [Caching(CachingMethod.Remove, "GetClassroom_InfoData")]
        void InsertClassroom_InfoData(Classroom_Info entity);
        [Caching(CachingMethod.Get)]
        List<Classroom_Info> GetClassroom_InfoData();
    }

实现很简单,只是一个测试而以

   public class Classroom_InfoRepository : TsingDa_NewLearningBarRepository<Classroom_Info>, IClassroom_InfoRepository
    {
        public void InsertClassroom_InfoData(Classroom_Info entity)
        {
            base.Insert(entity);
        }
        public List<Classroom_Info> GetClassroom_InfoData()
        {
            return base.GetModel().ToList();
        }
    }

 本文转自博客园张占岭(仓储大叔)的博客,原文链接:DDD~WCF做中间件,实现多个项目的缓存共享,如需转载请自行联系原博主。

目录
相关文章
|
4月前
|
存储 缓存 中间件
|
20天前
|
缓存 开发框架 移动开发
uni-app:下载使用uni&创建项目&和小程序链接&数据缓存&小程序打包 (一)
uni-app 是一个跨平台的开发框架,它允许开发者使用 Vue.js 来构建应用程序,并能够同时发布到多个平台,如微信小程序、支付宝小程序、H5、App(通过DCloud的打包服务)等。uni-app 的目标是通过统一的代码库,简化多平台开发过程,提高开发效率。 在这一部分中,我们将逐步介绍如何下载和使用uni-app、创建一个新的项目、如何将项目链接到小程序,以及实现数据缓存的基本方法。
|
2月前
|
缓存 NoSQL Java
瑞吉外卖项目笔记+踩坑2——缓存、读写分离优化
缓存菜品、套餐数据、mysql主从复制实现读写分离、前后端分离
瑞吉外卖项目笔记+踩坑2——缓存、读写分离优化
|
3月前
|
缓存 开发框架 .NET
看看 Asp.net core Webapi 项目如何优雅地使用内存缓存
看看 Asp.net core Webapi 项目如何优雅地使用内存缓存
|
3月前
|
存储 缓存 开发框架
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
|
5月前
|
缓存 NoSQL 中间件
应对数据库不断膨胀的数据:缓存和队列中间件
【6月更文挑战第5天】该文探讨了优化数据库使用以提升应用系统性能的策略。文中建议利用Redis缓存和MQ消息队列作为辅助工具,以进一步优化性能和减少资源消耗。
121 2
应对数据库不断膨胀的数据:缓存和队列中间件
|
5月前
|
敏捷开发 缓存 测试技术
阿里云云效产品使用问题之构建Vue3项目,怎么让node_modules缓存下来
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
6月前
|
存储 缓存 监控
中间件Read-Through Cache(直读缓存)策略实现方式
【5月更文挑战第11天】中间件Read-Through Cache(直读缓存)策略实现方式
77 4
中间件Read-Through Cache(直读缓存)策略实现方式
|
6月前
|
消息中间件 缓存 监控
中间件如果缓存中存在所需的数据(缓存命中)
【5月更文挑战第12天】中间件如果缓存中存在所需的数据(缓存命中)
51 3
|
6月前
|
存储 缓存 监控