关于.NET动态代理的介绍和应用简介

2016-02-19 12:19 16 1 收藏

今天天气好晴朗处处好风光,好天气好开始,图老师又来和大家分享啦。下面给大家推荐关于.NET动态代理的介绍和应用简介,希望大家看完后也有个好心情,快快行动吧!

【 tulaoshi.com - Web开发 】

引言

  假如现在我们有这样在这个示例中我将使用尽可能简单的逻辑实现所有功能需求,这将更突出我们所要解决的核心问题。例子是一个简单计算器类:

public class Calculator
{
 public int Add(int x, int y) { return x + y; }
}
  这个类再简单不过了,不过若你将它想象为一个可能更复杂的业务处理类的时候,你将面临除了核心功能实现之外的更多处理细节,比如说:权限控制、审计日志、性能监测、缓冲处理、事务环境等等。为简单起见,我们首先为该类增加记录日志的功能,该功能要求将对每个方法的调用和处理结果输出到Console中,如下:

public class Calculator
{
 public int Add(int x, int y)
 {
  Console.Write("Add({0},{1})", x, y);
  int result = x + y;
  Console.WriteLine(" = {0}", result);
  return result;
 }
}
  再简单不过了,对吧?现在我们需要为该方法实现性能监测,如下:

public class Calculator
{
 public int Add(int x, int y)
 {
  Console.Write("Add({0},{1})", x, y);
  DateTime TimeBegin = System.DateTime.Now;
  int result = x + y;
  TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
  Console.Write(" [{0}] ", TimeInter);
  Console.WriteLine(" = {0}", result);
  return result;
 }
}
  此时你已经感觉到,虽然我们实现了所需的功能,但是在一个方法中堆叠了处理各类事宜的不同代码。虽然在这个简单例子中不会感觉有什么不爽,但是请你想象一下如果我们将为该类添加第二个方法时会发生什么事情:

public class Calculator
{
 public int Add(int x, int y)
 {
  Console.Write("Add({0},{1})", x, y);
  DateTime TimeBegin = System.DateTime.Now;
  int result = x + y;
  TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
  Console.Write(" [{0}] ", TimeInter);
  Console.WriteLine(" = {0}", result);
  return result;
 }
 public int Subtract(int x, int y)
 {
  Console.Write("Subtract({0},{1})", x, y);
  DateTime TimeBegin = System.DateTime.Now;
  int result = x - y;
  TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
  Console.Write(" [{0}] ", TimeInter);
  Console.WriteLine(" = {0}", result);
  return result;
 }
}
  在两个方法中已经明显出现重复代码了,这可不是一个好的解决办法——想想一下如果我们的计算器有10个方法呢?如果我们还有类似于计算器类的另外数十个类呢?如果我们还有更多的方法级功能要实现呢(权限控制、事务管理……)?在企业级应用开发中,这可是一个经常会遇的问题。为清楚起见,我们将问题分解成两部分,首要的问题是代码职责混淆,其次则是同样的代码逻辑反复多次——这些问题都将导致开发管理、代码编写与维护的各种困难。

  方案一:自己手动编写代理解决

  1、首先 我们定义接口ICalculator:

using System;
namespace Proxy
{
 public interface ICalculator
 {
  int Add(int x, int y);
  int Subtract(int x, int y);
 }
}
  2、具体实现一个接口:

using System;
namespace Proxy
{
 public class Calculator:ICalculator
 {
  public virtual int Add(int x, int y)
  {
   int result = x + y;
   return result;
  }
  public virtual int Subtract(int x, int y)
  {
   int result = x - y;
   return result;
  }
 }
}  3、编写增加日志和性能检测功能的代理类

  增加记录日志的功能,即功能要求将对每个方法的调用和处理结果输出到Console;增加性能监测。

  有两种实现方式 ,注释了其中的一种

using System;
namespace Proxy
{
 // /// summary
 // /// CalProxy 的摘要说明。
 // /// /summary
 // public class CalProxy:ICalculator
 // {
 // private Calculator _Calculator;
 // public CalProxy()
 // {
 // this._Calculator=new Calculator();
 // }
 // private DateTime TimeBegin = System.DateTime.Now;
 // private void PreDoSomething(int x, int y)
 // {
 // TimeBegin = System.DateTime.Now;
 // Console.Write("Number({0},{1})n", x, y);
 // }
 // //实现add
 // public virtual int Add(int x, int y)
 // {
 // this.PreDoSomething(x,y);
 // int result = this._Calculator.Add(x,y);
 // this.PostDoSomething(result);
 // return result;
 // }
 // //实现sub
 // public virtual int Subtract(int x, int y)
 // {
 // this.PreDoSomething(x,y);
 // int result = this._Calculator.Subtract(x,y);
 // this.PostDoSomething(result);
 // return result;
 // }
 // private void PostDoSomething(int result)
 // {
 // TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
 // Console.Write(" 运行时间[{0}]n ", TimeInter);
 // Console.WriteLine(" 运行结果= {0}n", result);
 // }
 // }
 /// summary
 /// CalProxy 的摘要说明。
 /// /summary

 public class CalProxy:Calculator
 {
  public CalProxy()
  {}
  private DateTime TimeBegin = System.DateTime.Now;
  private void PreDoSomething(int x, int y)
  {
   TimeBegin = System.DateTime.Now;
   Console.Write("Number({0},{1})n", x, y);
  }
  //实现add
  public override int Add(int x, int y)
  {
   this.PreDoSomething(x,y);
   int result = base.Add(x,y);
   this.PostDoSomething(result);
   return result;
  }
  //实现sub
  public override int Subtract(int x, int y)
  {
   this.PreDoSomething(x,y);
   int result = base.Subtract(x,y);
   this.PostDoSomething(result);
   return result;
  }
  private void PostDoSomething(int result)
  {
   TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
   Console.Write(" 运行时间[{0}]n ", TimeInter);
   Console.WriteLine(" 运行结果= {0}n", result);
  }
 }
}
  4、外界的调用方式

ICalculator ICal=new Proxy.CalProxy();

ICal.Add(5,3);

ICal.Subtract(7,2);
  运行程序的结果:

Number(5,3)

  运行时间[00:00:02.0156250]

  运行结果= 8

  Number(7,2)

  运行时间[00:00:03]

  运行结果= 5

  方案二:通过使用Castle.DynamicProxy,实现Iinterceptor解决

  步骤1,2与解决问题

  3、实现StandardInterceptor,增加日志和性能监测功能

  StandardInterceptor是接口Iinterceptor的一个实现类,我们实现StandardInterceptor

using System;
using System.Collections;
using Castle.DynamicProxy;

namespace Proxy
{
 /// summary
 /// ProxyInterceptor 拦截器 实现了日志和性能监测
 /// /summary

 public class ProxyInterceptor:StandardInterceptor
 {
  private System.DateTime TimeBegin=System.DateTime.Now;
  public ProxyInterceptor()
  {}
  protected override void PostProceed(IInvocation invocation, ref object returnValue, params object[] arguments)
  {
   TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
   Console.Write(" 运行时间[{0}]n ", TimeInter);
   Console.WriteLine(" 运行结果= {0}n", returnValue);
   base.PostProceed(invocation, ref returnValue, arguments);
  }
  protected override void PreProceed(IInvocation invocation, params object[] args)
  {
   Console.Write("Number({0},{1})n", args[0], args[1]);
   TimeBegin=System.DateTime.Now;
   base.PreProceed(invocation, args);
  }
  public override object Intercept(IInvocation invocation, params object[] args)
  {
   PreProceed(invocation, args);
   object retValue = invocation.Proceed( args );
   PostProceed(invocation, ref retValue, args);
   return retValue;
  }
 }
}
  4、使用Castle.DynamicProxy调用

ProxyGenerator generator = new ProxyGenerator();
object proxy = generator.CreateClassProxy(typeof(Calculator), new ProxyInterceptor());
ICalculator ICalCastle=proxy as ICalculator;
ICalCastle.Add(5,3);
ICalCastle.Subtract(7,2);


  实现过程:首先通过代码生成完成一个代理类,该代理类继承自要织入的类。然后在代理类中覆盖要拦截的方法,并在覆盖的方法中封装Invocation对象,并传给用户传入的Intercepter对象的Intercept方法。在Intercept方法依次调用Intercepter的PreProcess,通过Invocation传入的Delegate指向的回调函数,Intercepter的PostProcess方法,从而达到拦截的目的。

  意义

  在aop领域 可以将日志,事务,缓存等附加功能用此实现。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

来源:http://www.tulaoshi.com/n/20160219/1600593.html

延伸阅读
Microsoft .NET Romoting 框架简介 Paddy Srinivasan Microsoft Corporation 2001 年 1 月 摘要:本文介绍 Microsoft .NET Romoting 框架的基本原理。除了介绍组成 .NET Romoting 框架的主要组件外,还介绍 .NET Remoting 与分布式对象通信的几种方案。 目录 简介 .NET Remoting 对象 集成 .NET Remoting 对象 .NET Remoting 元数据和...
如何简单、经济地把自己的局域网连入Internet,如何利用有限的IP地址使更多的机器上网受到普遍关注,利用Proxy Server可以很好地解决这些问题。下面以微软公司开发的Microsoft Proxy Server为例,对其具体配置做一简要讨论。 A. Microsoft Proxy Server 的设置: Microsoft Proxy Server是由两个服务器软件组成,即Web Proxy 和WinSock Pro...
在子类和父类里面有同名函数的时候,如果生成一个子类的对象,并在子类的对象里面调用这个函数,那么到底会是调用的是谁的函数呢?例如 class Base{ int i=47; int f(){ return g(); } int g(){ return i; } } class Dervied extends Base{ int i=27; int g(){ file://override父类里面的方法 return i; } } public class test { p...
标签: vb
By Steven Smith from aspalliance.com Yknow, theres this really cool library in .NET for dynamically creating images on the fly. However, this article has nothing to do with that, so if thats what youre looking for, stop now. What this article is about is very simple -- how to use a single line of code (via a compo...
标签: Web开发
一、 摘要 本文简单阐述了 Proxy 模式及具体说明了如何在 PHP4 中实现动态代理,本文只是给出了一个实现的方法的原型。由于水平有限,有任何意见和建议请反馈给 Binzy [ Binzy at JustDN dot Com ]。 二、 概述 在我们开始实现 Dynamic Proxy 之前,也许我们应该先了解一下什么是 Proxy 和它有什么用。下面是一篇来自博客堂...

经验教程

980

收藏

41
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部