本文簡單告訴大家如何在 .NET Core 裏面使用 AOP 切面編程,使用 DispatchProxy 做任意接口的動態代理實現
使用 DispatchProxy 有一些限制,如只能創建接口的實例。使用 DispatchProxy 可以讓咱做到從無中創建出某個實例,這個實例繼承咱想要的接口
首先需要創建某個動態代理類繼承 DispatchProxy 類,例如創建 Foo 類。此時需要實現 Invoke 接口,這個接口的含義是當代碼調用接口裏面的函數,包括屬性的設置和獲取函數的時候將會進入 Invoke 方法
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
// 忽略代碼
}
因此通過 Invoke 方法可以假裝自己是對應的接口的實現,可以進行隨意更改執行邏輯以及修改返回值
而 DispatchProxy 另一個核心方法是靜態的 Create 方法,這個方法要求傳入兩個泛形,第一個類型是想要創建出來的實例繼承的接口,第二個類型是某個繼承 DispatchProxy 的類
例如咱定義了一個 IF1 的接口,此時可以在 Foo 添加如下代碼創建出一個不存在的類型實例,這個實例繼承了 IF1 接口
public class Foo : DispatchProxy
{
public static T GetObject<T>()
{
return DispatchProxy.Create<T, Foo>();
}
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
return "lindexi";
}
}
假設 IF1 的定義如下
interface IF1
{
string F2();
}
此時的使用方法如下
Console.WriteLine(Foo.GetObject<IF1>().F2());
執行代碼可以看到輸出了 lindexi
也就是實際調用了 Foo 方法
可以看到 DispatchProxy 的作用就是提供靜態方法用於創建繼承指定接口的對象,同時讓繼承 DispatchProxy 的類可以拿到接口所調用的方法,用來修改執行邏輯和返回值
一個實際的使用的例子,提供了調用某個對象的每個方法之前給這個對象調用方法記日誌,這是最簡便的記日誌的方法了,儘管性能很渣
public class LoggingAdvice<T> : DispatchProxy
{
private T Object { set; get; }
public static T CreateLogging(Func<T> creator)
{
object proxy = DispatchProxy.Create<T, LoggingAdvice<T>>();
((LoggingAdvice<T>)proxy).Object = creator();
return (T)proxy;
}
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
Console.WriteLine($"開始執行 {targetMethod.Name}");
var result = targetMethod.Invoke(Object, args);
Console.WriteLine($"執行完成 {targetMethod.Name}");
return result;
}
}
此時就能做到在方法執行前後添加日誌,如這裏有一個接口和一個類,使用方法請參考以下示例
class Program
{
static void Main(string[] args)
{
var foo = LoggingAdvice<IF1>.CreateLogging(() => new Foo());
foo.F2();
}
}
interface IF1
{
string F2();
}
class Foo : IF1
{
/// <inheritdoc />
public string F2()
{
return "lindexi";
}
}
參考
在.NET Core中使用DispatchProxy“實現”非公開的接口 - LamondLu - 博客園
使用.net core中的類DispatchProxy實現AOP - 歐陽.NET - 博客園
我搭建了自己的博客 https://blog.lindexi.com/ 歡迎大家訪問,裏面有很多新的博客。只有在我看到博客寫成熟之後纔會放在csdn或博客園,但是一旦發佈了就不再更新
如果在博客看到有任何不懂的,歡迎交流,我搭建了 dotnet 職業技術學院 歡迎大家加入
如有不方便在博客評論的問題,可以加我 QQ 2844808902 交流
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名林德熙(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我聯繫。