第九回 Microsoft.Practices.Unity.Interception实现基于数据集的缓存(针对六,七,八讲的具体概念和配置的解说)

返回目录

概念

Microsoft.Practices.Unity.Interception是一个拦截器,它隶属于Microsoft.Practices.Unity组成之中,主要完成AOP的功能,而实现AOP方法拦截(页向切面)的基础就是IoC,我们需要配置相关接口或者类型的IoC方式,然后在生产对象时,使用Unity的方法进行动态生产对象,这时,你的Interception拦截器也会起作用!

相关技术

IoC: 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题。 控制反转一般又被称为依赖注入(Dependency Injection,简称DI)。即将配置中的对象,动态注入到项目程序当中,使程序的某个功能可以动态进行切换。

AOP: 面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),是软件开发中的一个热点。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

一般用它来实现:日志记录,性能统计,安全控制,事务处理,异常处理等等。

持久化方式

目前我的Project.UnityCaching组件支持Microsoft.Practices.EnterpriseLibrary.Caching和Redis两种数据持久化的方式,前者也是Microsoft.Practices. EnterpriseLibrary企业库的一部分,主要实现内存持久化(也可以实现文件持久化),主要用在单台WEB服务器上;后者可以单独部署到一台或者多台服务器上,主要实现分布式缓存,它是未来的大数据的一个方向。

键名组成

缓存解决方案名_命名空间_方法名,其中缓存解决方案名可以自己去配置,对应config中的CacheProjectName节点,而键对应的值采用字典类型,字典的键对应方法的各参数的组合。

涉及到的相关程序集

IoC基础库程序集

Redis基础库程序集

Project.Frameworks自封装程序集

配置文件中进行对IoC,AoP的配置

  <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="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" />
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"  />
    <section name="RedisConfig" type="Redis.Client.RedisConfigInfo, Redis.Client"/>
  </configSections>

  <RedisConfig WriteServerList="127.0.0.1:6379" ReadServerList="127.0.0.1:6379" MaxWritePoolSize="60" MaxReadPoolSize="60" AutoStart="true" LocalCacheTime="180" RecordeLog="false">
  </RedisConfig>

  <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>

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />

    <container>
      <!--泛型类型注入,数据仓储服务注入,可以由ef,linq,ado,memory,file,nosql等方式实现-->
      <register type="IRepository.Core.IUnitOfWork,IRepository.Core" mapTo="NLayer_IoC_Demo.Entity.backgroundTestIoCEntities,NLayer_IoC_Demo.Entity" />
      <!--使用redis作为持久化存储-->
      <!--<register type="IRepository.Core.IRepository`1,IRepository.Core" mapTo="Redis.Data.Core.RedisRepository`1,Redis.Data.Core" />-->
      <!--使用SQLSERVER作为持久化存储-->
      <register type="IRepository.Core.IRepository`1,IRepository.Core" mapTo="NLayer_IoC_Demo.DATA.backgroundRepositoryBase`1,NLayer_IoC_Demo.DATA" />
      <register type="IRepository.Core.IExtensionRepository`1,IRepository.Core" mapTo="NLayer_IoC_Demo.DATA.backgroundRepositoryBase`1,NLayer_IoC_Demo.DATA" />

      <!-- AOP注入 -->
      <extension type="Interception" />
      <register type="NLayer_IoC_Demo.BLL.IUserService,NLayer_IoC_Demo.BLL" mapTo="NLayer_IoC_Demo.BLL.UserService,NLayer_IoC_Demo.BLL" >
        <!--接口拦截-->
        <interceptor type="InterfaceInterceptor" />
        <!--缓存注入-->
        <interceptionBehavior type="Project.UnityCaching.CachingBehavior,Project.UnityCaching"/>
      </register>

      <register type="NLayer_IoC_Demo.BLL.OrderService,NLayer_IoC_Demo.BLL" >
        <!--接口拦截-->
        <interceptor  type="VirtualMethodInterceptor" />
        <!--虚方法注入,生成派生类进行拦截,让我们省去了建立接口的时间,不错的选择-->
        <!--Transparent Proxy Interceptor -->
        <!--它是注入所有的virutal method ,method,interface,但它的性能太差了-->
        <!--缓存注入-->
        <interceptionBehavior type="Project.UnityCaching.CachingBehavior,Project.UnityCaching"/>
      </register>

      <register type="Project.InterceptionBehaviors.IHandle, Project.InterceptionBehaviors" mapTo="Project.InterceptionBehaviors.StandardHandle, Project.InterceptionBehaviors">
        <!--接口拦截-->
        <interceptor type="InterfaceInterceptor" />
        <interceptionBehavior  type="NLayer_IoC_Demo.BLL.AOP.LoggerBehavior,NLayer_IoC_Demo.BLL" />
      </register>

    </container>
  </unity>

  <connectionStrings>
    <add name="backgroundTestIoCEntities" connectionString="metadata=res://*/background.csdl|res://*/background.ssdl|res://*/background.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=backgroundTestIoC;persist security info=True;user id=sa;password=zzl123;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-NLayer_IoC_Demo-20141024091423;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-NLayer_IoC_Demo-20141024091423.mdf" providerName="System.Data.SqlClient" />
  </connectionStrings>

使用时的相关注意要点

  1. Unity组件中引入了服务定位器ServiceLocator的概念,它可以使我们不引用目标程序集,而自动在bin目录自动去定位。
  2. 对于Redis方式的缓存来说,进行缓存的实体类需要被声明为Serializable特性。
  3. 实现IoC,AoP时,只引用需要的程序集,而不用将所有Microsoft.Practices.Unity组件都引入,在程序进行编译时,这些需要的程序集会自动添加到UI项目的BIN目录。
  4. 方法拦截这块有三种,但TransparentProxyInterceptor由于性能太差,我们并不提倡使用,项目中我们主要使用VirtualMethodInterceptor对于虚方法的拦截和InterfaceInterceptor对于接口的拦截,两种方式各有好处,如果实现方式比较单一,可以直接使用虚方法注入,这样可以省去写接口的代码量。

返回目录

时间: 2024-08-10 16:03:59

第九回 Microsoft.Practices.Unity.Interception实现基于数据集的缓存(针对六,七,八讲的具体概念和配置的解说)的相关文章

Microsoft.Practices.Unity AOP unity 3.x

上一文 Microsoft.Practices.Unity mvc controller 注入 本文记录为主,代码取自网络各大神,本地测试通过并记录在案. 内容:AOP 切面编程 核心代码:标的有注释 using Microsoft.Practices.Unity; using Microsoft.Practices.Unity.InterceptionExtension; using System; using System.Collections.Generic; using System.

利用Microsoft.Practices.Unity的拦截技术,实现.NET中的AOP

1.记住这个单词的意思:Interception(拦截) 2.首先说一下原理和背景 原理:所谓的AOP就是面向切面编程,这里不多说,百度搜索. 目的:个人认为是为了解耦,部分代码跟业务代码分离,业务代码里面不掺杂其它功能,比如:记录异常.记录操作日志. 背景:项目基本功能已完成,产品要求记录用户的操作日志,新增的时候记录某人在某时做了某事(包括详细的信息,比如新增了哪些字段或者修改了哪些字段).于是着手在业务代码里写了大量的关于记录操作日志的代码,怎么看怎么别扭,像是被XX了的感觉. 3.考虑解

Microsoft.Practices.Unity 通用类

类库的用法网上有很多,就不多说了,下面稍微封装了一下,记个笔记. 结合泛型接口类型和配置文件,得到IUnityContainer实例存于键值对中. 1 namespace Containers 2 { 3 public sealed class ObjectContainer 4 { 5 //fields 6 private static readonly object containerLock = new object(); 7 private static Dictionary<strin

Microsoft.Practices.Unity入门

Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入(Constructor Injection).属性注入(Property Injection),以及方法调用注入(Method Call Injection).现在Unity最新的版本的1.2版,可以在微软的开源站点http://unity.codeplex.com下载最新的发布版本和文档.通过使用Uni

VS - Microsoft.Practices.Unity

PM>  Install-Package Unity Web.config <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration" /> </configSections> <

使用Microsoft.Practices.Unity 依赖注入

Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入(Constructor Injection).属性注入(Property Injection),以及方法调用注入(Method Call Injection). 假设我们有下面的场景代码,在代码里面有一个很简单的customer对象,customer 对象有个save 方法, 这个方法通过调用ICusto

采用EntLib5.0(Unity+Interception+Caching)实现项目中可用的Caching机制

看了园子里很多介绍Caching的文章,多数都只介绍基本机制,对于Cache更新和依赖部分,更是只简单的实现ICacheItemRefreshAction接口,这在实际项目中是远远不够的.实际项目中,至少应该考虑以下3点: 外部数据:通过外部服务,从其他系统取来的数据.我们无法控制,也不知道啥时候会被更新.对于这部分数据,我们采用定时更新的策略,默认1小时更新1次,可配置. 内部数据:系统自己产生的数据,可以完全掌控.对这部分数据,我们实现ICacheItemRefreshAction接口,一旦

Unity实现AOP(用于实现缓存)

先下载这个NUGET包. 个人理解UINITY是在IOC上实现的AOP(自己试验了好多次),所以先定义接口跟实现类. namespace Cache { public class Talk : ITalk { [Caching(CachingMethod.Get)] public System.Collections.Generic.List<string> GetData() { Data.UpData(); return Data.GetData(); } } } namespace Ca

DI 依赖注入之unity的MVC版本使用Microsoft.Practices.Unity1.2与2.0版本对比

DI 依赖注入之unity的MVC版本使用Microsoft.Practices.Unity1.2与2.0版本对比 参考:https://www.cnblogs.com/xishuai/p/3670292.html 参考:https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff660914(v=pandp.20)?redirectedfrom=MSDN#config_registerelement 必读: 在unity1.2中我们