考虑在.NET框架中使用类层次结构定义的命名空间。
namespace OfficialDotnetNS
{
namespace officialNS.Bases
{
public class BaseOfA : IFakeA, IFakeB
{
protected void Driver(Stream stream){ this.DriveFoo(stream); };
protected internal virtual void DriveFoo(Stream stream);
}
}
public abstract class A : officialNS.Bases.BaseofA
{
protected internal override void DriveFoo(Stream stream){ this.Foo(stream); };
protected virtual void Foo(String stream);
}
public class B : A {}
public class C : A {}
public class D : A {}
// and 50+ similar classes derived from A
}
我有BaseofA
个对象,当我致电Driver(stream)
时,它会调用Foo
的{{1}}和合适的派生类。{/ p>
现在,我想用相同代码覆盖A
,因此从Foo()
派生的所有类都会继承此自定义实现。
一种方法是为每个类编写自定义包装器:
A
我们可以使用反射或其他技术来做到这一点而不重复代码吗?
答案 0 :(得分:1)
是。它被称为代理,它是实体框架使用的技术。有几种方法可以实现这一目标,但最好的IMO是CastleProject DynamicProxy。
例如(一个简化的案例,但我认为这可以做你想要的):
void Main()
{
var pg = new Castle.DynamicProxy.ProxyGenerator();
var typeA = typeof(A);
var interceptor =
new FooInterceptor(
str => Console.WriteLine("intercepted {0}", str));
IEnumerable<A> objs = Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(t => t.IsSubclassOf(typeA))
.Select(t => (A)(pg.CreateClassProxy(t, interceptor)));
foreach(A a in objs)
{
a.CallFoo("hello world");
}
}
public class A
{
public void CallFoo(string someString){
Foo(someString);
}
protected virtual void Foo(string someString)
{
Console.WriteLine("base Foo {0}", someString);
}
}
public class B : A {}
public class C : A {}
public class D : A {}
public class FooInterceptor : IInterceptor
{
Action<string> interceptorDelegate;
public Interceptor(Action<string> interceptorDelegate)
{
this.interceptorDelegate = interceptorDelegate;
}
public void Intercept(IInvocation invocation)
{
var isFooCall = invocation.Method.Name == "Foo";
if(isFooCall)
{
interceptorDelegate
.Invoke((string)(invocation.Arguments[0]));
}
else
{
invocation.Proceed();
}
}
}