麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 編程 > .NET > 正文

關(guān)于.NET動(dòng)態(tài)代理的介紹和應(yīng)用簡(jiǎn)介

2020-01-18 01:53:47
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
  引言

  假如現(xiàn)在我們有這樣在這個(gè)示例中我將使用盡可能簡(jiǎn)單的邏輯實(shí)現(xiàn)所有功能需求,這將更突出我們所要解決的核心問(wèn)題。例子是一個(gè)簡(jiǎn)單計(jì)算器類:

public class Calculator
{
 public int Add(int x, int y) { return x + y; }
}

  這個(gè)類再簡(jiǎn)單不過(guò)了,不過(guò)若你將它想象為一個(gè)可能更復(fù)雜的業(yè)務(wù)處理類的時(shí)候,你將面臨除了核心功能實(shí)現(xiàn)之外的更多處理細(xì)節(jié),比如說(shuō):權(quán)限控制、審計(jì)日志、性能監(jiān)測(cè)、緩沖處理、事務(wù)環(huán)境等等。為簡(jiǎn)單起見(jiàn),我們首先為該類增加記錄日志的功能,該功能要求將對(duì)每個(gè)方法的調(diào)用和處理結(jié)果輸出到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;
 }
}

  再簡(jiǎn)單不過(guò)了,對(duì)吧?現(xiàn)在我們需要為該方法實(shí)現(xiàn)性能監(jiān)測(cè),如下:

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

  此時(shí)你已經(jīng)感覺(jué)到,雖然我們實(shí)現(xiàn)了所需的功能,但是在一個(gè)方法中堆疊了處理各類事宜的不同代碼。雖然在這個(gè)簡(jiǎn)單例子中不會(huì)感覺(jué)有什么不爽,但是請(qǐng)你想象一下如果我們將為該類添加第二個(gè)方法時(shí)會(huì)發(fā)生什么事情:

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

  在兩個(gè)方法中已經(jīng)明顯出現(xiàn)重復(fù)代碼了,這可不是一個(gè)好的解決辦法――想想一下如果我們的計(jì)算器有10個(gè)方法呢?如果我們還有類似于計(jì)算器類的另外數(shù)十個(gè)類呢?如果我們還有更多的方法級(jí)功能要實(shí)現(xiàn)呢(權(quán)限控制、事務(wù)管理……)?在企業(yè)級(jí)應(yīng)用開(kāi)發(fā)中,這可是一個(gè)經(jīng)常會(huì)遇的問(wèn)題。為清楚起見(jiàn),我們將問(wèn)題分解成兩部分,首要的問(wèn)題是代碼職責(zé)混淆,其次則是同樣的代碼邏輯反復(fù)多次――這些問(wèn)題都將導(dǎo)致開(kāi)發(fā)管理、代碼編寫與維護(hù)的各種困難。

  方案一:自己手動(dòng)編寫代理解決

  1、首先 我們定義接口ICalculator:

using System;
namespace Proxy
{
 public interface ICalculator
 {
  int Add(int x, int y);
  int Subtract(int x, int y);
 }
}

  2、具體實(shí)現(xiàn)一個(gè)接口:

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、編寫增加日志和性能檢測(cè)功能的代理類

  增加記錄日志的功能,即功能要求將對(duì)每個(gè)方法的調(diào)用和處理結(jié)果輸出到Console;增加性能監(jiān)測(cè)。

  有兩種實(shí)現(xiàn)方式 ,注釋了其中的一種

using System;
namespace Proxy
{
 // /// <summary>
 // /// CalProxy 的摘要說(shuō)明。
 // /// </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);
 // }
 // //實(shí)現(xiàn)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;
 // }
 // //實(shí)現(xiàn)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(" 運(yùn)行時(shí)間[{0}]/n ", TimeInter);
 // Console.WriteLine(" 運(yùn)行結(jié)果= {0}/n", result);
 // }
 // }
 /// <summary>
 /// CalProxy 的摘要說(shuō)明。
 /// </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);
  }
  //實(shí)現(xiàn)add
  public override int Add(int x, int y)
  {
   this.PreDoSomething(x,y);
   int result = base.Add(x,y);
   this.PostDoSomething(result);
   return result;
  }
  //實(shí)現(xiàn)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(" 運(yùn)行時(shí)間[{0}]/n ", TimeInter);
   Console.WriteLine(" 運(yùn)行結(jié)果= {0}/n", result);
  }
 }
}

  4、外界的調(diào)用方式

ICalculator ICal=new Proxy.CalProxy();

ICal.Add(5,3);

ICal.Subtract(7,2);

  運(yùn)行程序的結(jié)果:

Number(5,3)

  運(yùn)行時(shí)間[00:00:02.0156250]

  運(yùn)行結(jié)果= 8

  Number(7,2)

  運(yùn)行時(shí)間[00:00:03]

  運(yùn)行結(jié)果= 5

  方案二:通過(guò)使用Castle.DynamicProxy,實(shí)現(xiàn)Iinterceptor解決

  步驟1,2與解決問(wèn)題

  3、實(shí)現(xiàn)StandardInterceptor,增加日志和性能監(jiān)測(cè)功能

  StandardInterceptor是接口Iinterceptor的一個(gè)實(shí)現(xiàn)類,我們實(shí)現(xiàn)StandardInterceptor

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

namespace Proxy
{
 /// <summary>
 /// ProxyInterceptor 攔截器 實(shí)現(xiàn)了日志和性能監(jiān)測(cè)
 /// </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(" 運(yùn)行時(shí)間[{0}]/n ", TimeInter);
   Console.WriteLine(" 運(yùn)行結(jié)果= {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調(diào)用

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


  實(shí)現(xiàn)過(guò)程:首先通過(guò)代碼生成完成一個(gè)代理類,該代理類繼承自要織入的類。然后在代理類中覆蓋要攔截的方法,并在覆蓋的方法中封裝Invocation對(duì)象,并傳給用戶傳入的Intercepter對(duì)象的Intercept方法。在Intercept方法依次調(diào)用Intercepter的PreProcess,通過(guò)Invocation傳入的Delegate指向的回調(diào)函數(shù),Intercepter的PostProcess方法,從而達(dá)到攔截的目的。

  意義

  在aop領(lǐng)域 可以將日志,事務(wù),緩存等附加功能用此實(shí)現(xiàn)。

 

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 九九热在线免费观看视频 | 国产精品国产三级国产在线观看 | 一级大片视频 | 激情视频免费看 | 亚洲精品一区二区三区在线看 | 一级做受大片免费视频 | 久久逼逼| 97精品视频在线观看 | 中文区永久区 | 精国产品一区二区三区四季综 | 欧美a视频在线观看 | 亚洲第一页在线观看 | 草操影院 | 国产一区二区三区网站 | 九九热这里只有精品8 | 色av综合在线 | av免费在线观看国产 | 在线亚洲免费 | 免费毛片播放 | 欧美a级在线免费观看 | 精品一区二区久久久久久久网精 | h久久 | 国产一区免费观看 | 12av毛片 | 黄色av网站在线观看 | av免费在线观看国产 | 美国黄色毛片女人性生活片 | 草碰人人 | 看免费av | 亚洲va久久久噜噜噜久牛牛影视 | 免费黄色在线观看网站 | 欧美日韩一 | 国产电影精品久久 | 国产精品伊人久久 | 日美av在线| 精品成人国产在线观看男人呻吟 | 黄色网电影 | 九一免费版在线观看 | 一级成人黄色片 | 国产欧美日韩视频在线观看 | 成人区一区二区 |