截获泛型类中的方法调用
本文关键字:方法 调用 泛型类 | 更新日期: 2023-09-27 17:58:59
我有这个代码:
abstract class CommunicationChannel<Client> : IDisposable where Client : class, IDisposable {
protected Client client;
public void Open() {
try
{
client = CreateClient();
}
catch (Exception)
{
client.Dispose();
throw;
}
}
public virtual void Dispose() {
client.Dispose();
}
private Client CreateClient()
{
return Activator.CreateInstance<Client>();
}
}
class Communicator : CommunicationChannel<Client>
{
// here I have specific methods
void Method1(args) {
Open();
try {
client.Method1(args);
}
catch(Exception) {
// Cleanup
}
}
// this is getting too verbose already
void Method2(args) {
Open();
try {
client.Method2(args);
}
catch(Exception) {
// Cleanup
}
}
}
class Client: IDisposable {
public void Dispose()
{
}
}
我希望基类CommunicationChannel能够以某种方式截获所有与客户端相关的调用,并在将异常传播到派生类CommunicationChannel之前处理异常。基类的泛型参数可以包含不同的方法(在我的示例中,我们只有方法1)
理想情况下,我想要一个不必调用CommunicationChannel.CallMethod("Method1",args)的解决方案。
您可以将client
设为私有,并强制子类在Func
或Action
中访问它。然后您可以在逻辑之前/之后添加您:
abstract class CommunicationChannel<Client> : IDisposable where Client : class, IDisposable
{
private Client client;
protected TResult WithClient<TResult>(Func<Client, TResult> f)
{
this.Open();
try
{
return f(client);
}
catch (Exception)
{
//cleanup
}
return default(TResult);
}
protected void WithClient(Action<Client> act)
{
WithClient<object>(c => { act(c); return null; })
}
}
您的子类可以执行以下操作:
class Communicator : CommunicationChannel<Client>
{
bool Method1(args)
{
return WithClient<bool>(c => { return c.Method1(args); });
}
}
我认为这是使用AOP(面向方面编程)的一个很好的例子。
您可以设置一个方面,即OnEntry,执行Open方法并用OnException方法捕获异常。
然后你所要做的就是用属性装饰你想在上面使用该方面的方法
我将使用PostSharp:演示我的意思
public class CommunicationAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
var communicationObject = args.Instance as CommunicationObject;
communicationObject.Open();
args.FlowBehavior = FlowBehavior.Continue;
}
public override void OnException(MethodExecutionArgs args)
{
_logger.log(string.Format("Exception {0} has occured on method {1}", args.Exception, args.Method.Name));
}
}
然后,用这个属性装饰你的方法:
class Communicator : CommunicationChannel<Client>
{
[CommunicationAspect]
void Method1(args)
{
client.Method1(args);
}
[CommunicationAspect]
void Method2(args)
{
client.Method2(args);
}
}
PostSharp是一个很好的框架,它非常容易上手,我建议你研究一下。