求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
DDD~WCF做中间件,实现多个项目的缓存共享
 
作者 张占岭,火龙果软件    发布于 2014-02-13
 

事情是这样的,前台网站有些数据不希望每次都从数据库里读,所以,应该做个缓存,而引起缓存更新的入口来自网站的后台管理,而前台和后台被部署在不同的网站中,这时缓存的更新就成了问题,前台的缓存与后台的操作不能联系到一起,为了解决这个问题,我引入了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();
}
}
 
相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
 
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
 
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
 
分享到
 
 


使用decj简化Web前端开发
Web开发框架形成之旅
更有效率的使用Visual Studio
MVP+WCF+三层结构搭建框架
ASP.NET运行机制浅析【图解】
编写更好的C#代码
10个Visual Studio开发调试技巧
更多...   


.NET框架与分布式应用架构设计
.NET & WPF & WCF应用开发
UML&.Net架构设计
COM组件开发
.Net应用开发
InstallShield


日照港 .NET Framework & WCF应用开发
神华信息 .NET单元测试
北京 .Net应用软件系统架构
台达电子 .NET程序设计与开发
赛门铁克 C#与.NET架构设计
广东核电 .Net应用系统架构
更多...