ClassProxy Problems/Support

5 views
Skip to first unread message

Martin Mitterer

unread,
Jun 23, 2009, 3:54:55 AM6/23/09
to LinFu.Framework
I have several (conceptual) problems with class proxies.
Here's the code:

using LinFu.AOP.Interfaces;
using LinFu.Proxy;
using LinFu.Proxy.Interfaces;
using NUnit.Framework;

namespace LinFu.UnitTests {
[TestFixture]
public class ProxyInjectionTest {
public class Interceptor : IInterceptor {


public object Intercept(IInvocationInfo info) {
//how can I call the target method on the base class??
//In DP2 there is always invocation.Proceed(), why do
I have to code the reflection stuff by myself?

//I also don't want to use the interceptor constructor
for this use.
//info.TargetMethod.Invoke(_target, info.Arguments);


}


//I don't really want to write this code
//private readonly object _target;
//public LoggerInterceptor(object target) {
// _target = target;
// }



}

[Test]
public void Test() {
IProxyFactory factory = new ProxyFactory();

//Problem: CreateProxy doesn't support constructor
arguments, only a default constructor is created.
var c = factory.CreateProxy<Class1>(new Interceptor());
//there should be something like this: ...params object[]
args
//var c = factory.CreateProxy<Class1>(new Interceptor(),
new Class2(), new Class3());
// --> doing this via Interceptor is not very elegant in
my opinion
// ( ... new Interceptor(new Class2(), new Class3())
c.Execute();
}
}

public class Class1 {
private readonly Class2 _class2;
private readonly Class3 _class3;

public Class1(Class2 class2, Class3 class3) {
_class2 = class2;
_class3 = class3;
}

public virtual void Execute() {
_class2.Execute();
_class3.Execute();
}
}

public class Class2 {
public virtual void Execute() {}
}

public class Class3 {
public virtual void Execute() {}
}
}

Philip Laureano

unread,
Jun 23, 2009, 6:15:42 PM6/23/09
to linfufr...@googlegroups.com
Hi Martin,

I think the conceptual problem that you're having is because LinFu.Proxy doesn't work the same way Castle.DP2 does--the two libraries ultimately create dynamic proxies at runtime, but they're actually two different types of proxy generators.

The reason why you're having problems calling the base class on the target method is that the dynamic proxies that LinFu creates aren't full-fledged types--they're true proxies in the sense of the Proxy pattern. Their only purpose is to forward method calls to an actual type, and the proxies that LinFu generates have absolutely no concept of state, aside from the interceptor attached to the proxy. This makes LinFu more lightweight since you don't necessarily even need to construct the real type in order to have a proxy that 'acts' just like the real thing; all you need to do is attach the interceptor to the proxy instance and the client objects won't know the difference.

In other words, LinFu does not let you create proxies with constructor arguments because its proxies are only supposed to forward calls to an interceptor. If I had its proxies act as actual types, then I'd be violating the Single Responsibility Principle, and that just makes the design even more complicated. Castle, in contrast, is a hybrid proxy--you can construct its proxy types like normal objects, but the tradeoff is that you have to two different types of calls to make an interface proxy, and a class proxy.

With LinFu, you can create an interface or a class proxy using a single CreateProxy() method.

So if you expect LinFu to act exactly the same as Castle (or perhaps even have the same design), then I have to disappoint you. :)
Reply all
Reply to author
Forward
0 new messages