我可以创建一个包装器来拦截对实现某个接口的对象的所有调用吗?
本文关键字:接口 实现 对象 调用 创建 一个 包装 我可以 | 更新日期: 2023-09-27 18:08:23
假设我有一个接口IFoo
interface IFoo
{
int Bar();
int Bar2();
void VBar();
//etc,
}
我可以创建一个包装器,接受任何IFoo对象,并在实际调用之前/之后做一些事情吗?
。当我做这样的事情
IFoo wrappedFoo = new Wrapper<IFoo>(actualFooObject).Object;
wrappedFoo.Bar();
,那么wrapper。bar()方法实际执行如下内容
PreCall(); //some code that I can define in the wrapper
actualFooObject.Bar();
PostCall();
是否有一种简单而干净的方法来做到这一点?
对于这种方法,您可以使用代码契约。请参阅用户手册(pdf)的2.8 Interface Contracts
部分。
你可以使用AOP。我使用这个库已经有一段时间了:
http://www.postsharp.net/products如果您需要在PreCall()
和PostCall
上有一些东西,简单的方法是在代理基方法下包装
public abstract class ProxyBase
{
public void Execute()
{
PreCondition();
Call();
PostCondition();
}
private void PreCondition()
{
Console.WriteLine("ProxyBase.PreCondition()");
}
private void PostCondition()
{
Console.WriteLine("ProxyBase.PreCondition()");
}
protected abstract void Call();
}
public class AppProxy<T> : ProxyBase where T : IApp
{
private IApp _app;
public AppProxy<T> Init(IApp app)
{
_app = app;
return this;
}
protected override void Call()
{
Console.WriteLine("AppProxy.Call()");
_app.Call();
}
public IApp Object
{
get { return _app; }
}
}
public interface IApp
{
void Call();
}
public interface IFoo : IApp
{
}
public class ActualFoo : IApp
{
public void Call()
{
Console.WriteLine("ActualFoo.Call()");
}
}
class Program
{
static void Main(string[] args)
{
ActualFoo actualFoo = new ActualFoo();
var app = new AppProxy<IFoo>().Init(actualFoo);
app.Execute();
var o = app.Object as ActualFoo;
Console.ReadLine();
}
}
---------------输出--------------
ProxyBase.PreCondition ()
AppProxy.Call ()
ActualFoo.Call ()
ProxyBase.PreCondition ()
我看不出有什么"干净简单"的方法。
我能想到的最好的选择是写一个通用的Wrapper<T>
封装和T
的实例,并实现通用的Precall
和Postcall
方法:
public class Wrapper<T>
{
protected T _instance;
public Wrapper(T instance)
{
this._instance = instance;
}
protected virtual void Precall()
{
// do something
}
protected virtual void Postcall()
{
// do something
}
}
这样你就可以为接口IFoo
(或任何其他接口)编写自己的FooWrapper
,只需委托方法调用:
public class FooWrapper :Wrapper<IFoo>, IFoo
{
public FooWrapper(IFoo foo)
: base(foo)
{
}
public int Bar()
{
base.Precall(); return base._instance.Bar(); base.Postcall();
}
public int Bar2()
{
base.Precall(); return base._instance.Bar2(); base.Postcall();
}
public void VBar()
{
base.Precall(); base._instance.VBar(); base.Postcall();
}
}
你可以这样使用:
IFoo f = new ActualFooClass();
IFoo wf = new FooWrapper(f);
f.Bar();
当然,如果您的Precall
和Postcall
方法不是泛型的,那么使用Wrapper<T>
类就没有意义了。就用FooWrapper
吧