C# 代理应用:Cachable

放心,这次不是说设计模式中的代理模式,说的是C#的RealProxy的用法,主要用于:通过给class 贴标签,让class做更多的工作,比如判断是否存在缓存,有则直接返回缓存object,没有则保存为缓 存,等待下次请求是可以更快的获取数据(当然这只是其中一种常用用途,MVC的Action就是采用这种 方式)

下面是序列图:

.Net Object Generation interceptor属于.NET自身行为,不需要额外写代码。

Code Consumer指想调用RealObject来进行调用的对象,比如控制台程序,或者WEB程序。

ProxyAttribute里定义了具体代理类是哪个,这个代理类是自己 继承RealProxy写的一个代理类, 这个类中需要加入前置、后置、环绕等方法(具体根据需求)

下面我们来看具体如何在.Net中实现:

public class FollowAction
    {
        public bool StopExecute { get; set; }             //用于在前置方法中,指示是否停止执行真正的方法体,比如已经找到了cache value,因此不需要继续运行方法体的情况
        public object Result { get; set; }                //保存cache value的变量
    }

public abstract class CachableRealProxy : RealProxy
    {
        private MarshalByRefObject target;

        public MyAOPRealProxy(Type objType, MarshalByRefObject obj)
            : base(objType)
        {
            target = obj;
        }

        public override IMessage Invoke(IMessage msg)
        {
            IMessage retMsg = null;
            IMethodCallMessage methodCall = (IMethodCallMessage)msg;
            IMethodReturnMessage methodReturn = null;
            object[] copiedArgs = Array.CreateInstance(typeof(object), methodCall.Args.Length) as object[];
            methodCall.Args.CopyTo(copiedArgs, 0);
            if (msg is IConstructionCallMessage)
            {

                IConstructionCallMessage ccm = (IConstructionCallMessage)msg;
                RemotingServices.GetRealProxy(target).InitializeServerObject(ccm);
                ObjRef oRef = RemotingServices.Marshal(target);
                RemotingServices.Unmarshal(oRef);
                retMsg = EnterpriseServicesHelper.CreateConstructionReturnMessage(ccm, (MarshalByRefObject)this.GetTransparentProxy());

            }
            else
            {
                bool aopAttributeExists = false;
                object[] attrs = methodCall.MethodBase.GetCustomAttributes(false);
                if (attrs != null && attrs.Count() > 0)
                {
                    foreach(object o in attrs)
                    {
                        CachableAttribute attr = o as CachableAttribute;
                        if (attr != null)
                        {
                            aopAttributeExists = true;
                            break;
                        }
                    }
                }
                FollowAction follow=null;
                if (aopAttributeExists)
                    follow = this.PreProcess(msg);

                try
                {
                    object returnValue = null;
                    if (follow != null && follow.StopExecute)
                        returnValue = follow.Result;
                    else
                        returnValue = methodCall.MethodBase.Invoke(this.target, copiedArgs);
                    methodReturn = new ReturnMessage(returnValue, copiedArgs, copiedArgs.Length, methodCall.LogicalCallContext, methodCall);

                    if (follow == null || !follow.StopExecute)
                        if (aopAttributeExists)
                            this.PostProcess(msg, methodReturn);
                }
                catch (Exception ex)
                {
                    if (null != ex.InnerException)
                    {
                        methodReturn = new ReturnMessage(ex.InnerException, methodCall);
                    }
                    else
                    {
                        methodReturn = new ReturnMessage(ex, methodCall);
                    }
                }
                retMsg = methodReturn;

            }
            return retMsg;
        }

       public override FollowAction PreProcess(System.Runtime.Remoting.Messaging.IMessage requestMsg)  //处理前置方法
        {
            bool cacheDefinationTagExists = true;
            CachableAttribute cacheDefine = CheckCacheDefinationTag(requestMsg, ref cacheDefinationTagExists);
            if (!cacheDefinationTagExists)
                return null;

            string cacheKey = cacheDefine.GenerateCacheKey();
            object o=CacheManager.Instance().GetCacheCore().Get(cacheDefine.Location, cacheKey);
            if (o != null)
            {
                FollowAction follow = new FollowAction();
                follow.Result = o;
                follow.StopExecute = true;
                return follow;
            }

            return null;
        }

        public override void PostProcess(System.Runtime.Remoting.Messaging.IMessage requestMsg, System.Runtime.Remoting.Messaging.IMessage responseMsg)//处理后置方法
        {
            bool cacheDefinationTagExists = true;
            CachableAttribute cacheDefine = CheckCacheDefinationTag(requestMsg, ref cacheDefinationTagExists);
            if (!cacheDefinationTagExists)
                return;

            ReturnMessage returnMsg = (ReturnMessage)responseMsg;

            string cacheKey = cacheDefine.GenerateCacheKey();
            CacheManager.Instance().GetCacheCore().Set(cacheDefine.Location, cacheKey, returnMsg.ReturnValue);
        }
        private static CachableAttribute CheckCacheDefinationTag(System.Runtime.Remoting.Messaging.IMessage requestMsg, ref bool cacheDefinationTagExists)//Help函数
        {
            IMethodCallMessage methodCall = (IMethodCallMessage)requestMsg;
            object[] attrs = methodCall.MethodBase.GetCustomAttributes(typeof(CachableAttribute), false);
            if (attrs == null || attrs.Count() <= 0)
                cacheDefinationTagExists = false;
            CachableAttribute cacheDefine = attrs[0] as CachableAttribute;
            if (cacheDefine == null)
                cacheDefinationTagExists = false;
            return cacheDefine;
        }
    }

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索object
, c# remoting 多账套
, null
, public
imessage
c站、c语言、cf、ch、c罗,以便于您获取更多的相关知识。

时间: 2024-12-23 05:48:10

C# 代理应用:Cachable的相关文章

缓存子系统的设计方法

缓存子系统如何设计(Cachable tag, Memcache/redis support, xml config support, LRU/LFU/本地缓存命中率) 大家对这段代码肯定很熟悉吧: public List<UserInfo> SearchUsers(string userName) { string cacheKey=string.Format("SearchUsers_{0}", userName); List<UserInfo> users

大话设计模式之代理模式

代理模式的应用场合: 一,远程代理 二,虚拟代理 三,安全代理 简单来说,就是两个类共同实现接口,一个实现,一个调用这个实现.而调用实现的类,就是代理类. 针对书上的代码,我加了一个NAME变量和一个SHOWNAME方法.更加直观展示代理的细节. 1 /* 2 * Created by SharpDevelop. 3 * User: home 4 * Date: 2013/4/21 5 * Time: 9:33 6 * 7 * To change this template use Tools

ip-《TCP/IP 详解卷一》中90页中讲到,“由于子网号不相同,代理ARP不能使用”,这怎么理解?

问题描述 <TCP/IP 详解卷一>中90页中讲到,"由于子网号不相同,代理ARP不能使用",这怎么理解? <TCP/IP 详解卷一>中90页中讲到,"由于子网号不相同,代理ARP不能使用",这怎么理解? 解决方案 ARP主要用在一个子网中,用MAC地址来通信.数据链路层 不同子网,需要通过三层路由 解决方案二: 比如 N1 <-> GW <-> N2,N1和N2是同一个子网,GW上开启arp代理的效果是,N1和N2上

iOS UITableView代理方法详解

IOS UITableView的代理方法详解 一.补充 在上一篇博客中,http://my.oschina.net/u/2340880/blog/404605,我将IOS中tableView(表视图)的一些常用方法总结了一下,这篇将tableView的代理方法作了总结,对上一篇博客进行了补充. 二.UITableViewDataSourc(数据源代理) 1.必须实现的回调方法 返回每个分区的行数 - (NSInteger)tableView:(UITableView *)tableView nu

快速可扩展的Ajax流代理——提供持续下载跨域数据

简介 由于浏览器禁止跨域的XMLHTTP调用,所有的Ajax网站都必须有一个服务端代理来从外部域比如Flickr或者Digg来抓去内容.对客户端Javascript代码来说,一个XMLHttp的调用将请求传递给宿主在相同域里的服务端代理,然后由代理来从外部服务器上下载内容,并回传给客户端.通常,所有从外部服务器获取内容的Ajax站点都采用这种代理方案,除了一些罕见的使用JSONP的人.当网站上的许多组件正在从外部域下载内容时,这样的代理将会被大量地调用.所以,当代理开始被百万次地调用时,它将变成

JAVA核心层--反射--动态代理

本文发表于2010年,时间较早,部分问题解释不是十分准确,所以需要进一步了解,请参看2012年版本: java之架构基础-动态代理&cglib 要在JAVA技术上突破普通的层面,并拥有一翻设计理念的高度,除了要有很好的设计思维之外,反射在适当的使用下,将会把框架做得非常清晰,并且代码编写也非常简便. 在面向对象的编程中,我们为什么要忌讳去大量使用if else switch语句,因为这样写是将逻辑硬编码了,JAVA的思想就是将其配置化,一旦可配置化后,就逐渐可管理化,并随着产品的成熟逐步实现自动

java之架构基础-动态代理&amp;amp;cglib

本文核心主要参数动态代理和cglib: 在以前的文章中,有提及到动态代理,它要解决的就是,当我们的某些代码前面或后面都需要一些处理的时候,如写日志.事务控制.做agent.自动化代码跟踪等,此时会给你带来无限的方便,这是JVM级别的提供的一种代理机制,不过在这种机制下调用方法在JVM7出来前还没有invokeDynamic的时候,调用的效率是很低的,此时方法调用都是通过method的invoke去实现. 其基本原理是基于实现JVM提供的一个: InvocationHandler的接口,实现一个方

你真的了解iOS代理设计模式吗?

本文是投稿文章,作者:刘小壮 在项目中我们经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式来传递一些参数.这篇文章会涵盖代理的使用技巧和原理,以及代理的内存管理等方面的知识.我会通过这些方面的知识,带大家真正领略代理的奥妙.写的有点多,但都是干货,我能写下去,不知道你有没有耐心看下去.本人能力有限,如果文章中有什么问题或没有讲到的点,请帮忙指出,十分感谢! iOS中消息传递方式 在iOS中有很多种消息传递方式,这里先简单介绍一下各种消息传递方式. 通知:在iOS中由通

JDK和CGLIB生成动态代理类的区别

 关于动态代理和静态代理 当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象. 按照代理对象的创建时期不同,可以分为两种: 静态代理:事先写好代理对象类,在程序发布前就已经存在了: 动态代理:应用程序发布后,通过动态创建代理对象. 静态代理其实就是一个典型的代理模式实现,在代理类中包装一个被代理对象,然后影响被代理对象的行为,比较简单,代码就不放了. 其中动态代理又可分为:JDK动态代理和CGLIB代理. 1.JDK动态代理