From: hammett <ha...@uo...> - 2004-10-23 03:59:28
|
Guys, I've stopped for a while to analyze our strategy on proxying concrete classes. Just to set a common ground: MyClass x = new MyClass() ProxyGenerator generator = new ProxyGenerator(); StandardInvocationHandler handler = new StandardInvocationHandler(myClass); MyClass proxy = (MyClass) generator.CreateClassProxy( typeof(MyClass), handler ); -=- How it works? -=- The generator creates a dynamic type which extends MyClass and override all methods creating stubs. These stubs code are something like: public override void DoSomething( int val ) { MethodInfo m = MethodBase.GetMethodFromHandle( ldtoken method ); handler.Invoke( this, m, val ); } So every invocation has to delegate the to a "real" class instance. In the code above, the x will be the real instance. Thus we have two copies of the same class. Do we really need them? The DynamicProxy originally intented to proxy interfaces, and someway it grow offering proxy capabilities to concrete classes, but now I realize that the interface should be different. -=- Proposal -=- interface IClassInterceptor // better name? { object Intercept( IInvocation invocation ); } interface IInvocation { object[] Arguments { get; set; } object Proxy { get; set; } object Proceed(); } Now the user, instead of using a IInvocationHandler, should use ProxyGenerator generator = new ProxyGenerator(); DefaultClassInterceptor interceptor = new DefaultClassInterceptor(); MyClass proxy = (MyClass) generator.CreateClassProxy( typeof(MyClass), handler ); Now we dont have separate instances. When a method is invoked on the proxy, the Intercept is invoked. If the user invoke the Invocation.Proceed, the proxy calls the super class to invoke the real implementation. How do you like that? -=- Under the hood -=- I've played for five minutes, so I'm not sure if this is the best approach, with the best performance, but it relies on delegates. class MyClassProxy : MyClass { ... delegate void __MyClass_DoSomething(int x); public override void DoSomething(int x) { MethodInfo m = MethodBase.GetMethodFromHandle( ldtoken method ); InvocationImpl invocation = new InvocationImpl( this, m, new __MyClass_DoSomething(callback__DoSomething), x ); interceptor.Intercept( invocation ); } private void callback__DoSomething(int x) { base.DoSomething(x); } } class InvocationImpl : IInvocation { public InvocationImpl( object proxy, MethodInfo m, delegate call, params object[] args ) { .. } public object Proceed() { call.DynamicInvoke( args ); } } Yes, it works! But before I start to code this beast we need to agree on these interfaces. Also, can we think of something similar to interface proxies? We're close to the first non-beta release and once this is release, change interfaces will hurt users, and we don't want that. -- Cheers, hammett http://www.digitalcraftsmen.com.br/~hammett |
From: Deyan P. <de...@ho...> - 2004-10-23 12:31:09
|
Hi hammett, Why don't you simply generate something like the stuff below? I think that if you don't use runtime reflection the execution will be measurable with the unproxied execution, otherwise it's much slower ...: class MyClassProxy : MyClass { ... private IInvocationHandler _handler; public override object DoSomething(int x) { object result = null; if(!_handler.PreProcess(base, ref result)) return result; result = base.DoSomething(x); _handler.PostProcess(base, ref result); return result; } public override void DoSomethingElse(int x) { if(!_handler.PreProcess(base)) return; base.DoSomethingElse(x); _handler.PostProcess(base); return; } } Br, Deyan Petrov ----- Original Message ----- From: "hammett" <ha...@uo...> To: <asp...@li...> Sent: Saturday, October 23, 2004 9:59 AM Subject: [Aspectsharp-users] Proposal: Big Change > Guys, > > I've stopped for a while to analyze our strategy on proxying concrete > classes. Just to set a common ground: > > MyClass x = new MyClass() > > ProxyGenerator generator = new ProxyGenerator(); > StandardInvocationHandler handler = new > StandardInvocationHandler(myClass); > MyClass proxy = (MyClass) > generator.CreateClassProxy( typeof(MyClass), handler ); > > > -=- How it works? -=- > > The generator creates a dynamic type which extends MyClass and override all > methods creating stubs. These stubs code are something like: > > public override void DoSomething( int val ) > { > MethodInfo m = MethodBase.GetMethodFromHandle( ldtoken method ); > handler.Invoke( this, m, val ); > } > > So every invocation has to delegate the to a "real" class instance. In the > code above, the x will be the real instance. Thus we have two copies of the > same class. Do we really need them? > The DynamicProxy originally intented to proxy interfaces, and someway it > grow offering proxy capabilities to concrete classes, but now I realize that > the interface should be different. > > > -=- Proposal -=- > > interface IClassInterceptor // better name? > { > object Intercept( IInvocation invocation ); > } > > interface IInvocation > { > object[] Arguments { get; set; } > > object Proxy { get; set; } > > object Proceed(); > } > > > Now the user, instead of using a IInvocationHandler, should use > > ProxyGenerator generator = new ProxyGenerator(); > DefaultClassInterceptor interceptor = new DefaultClassInterceptor(); > > MyClass proxy = (MyClass) generator.CreateClassProxy( typeof(MyClass), > handler ); > > Now we dont have separate instances. When a method is invoked on the proxy, > the Intercept is invoked. If the user invoke the Invocation.Proceed, the > proxy calls the super class to invoke the real implementation. How do you > like that? > > > -=- Under the hood -=- > > I've played for five minutes, so I'm not sure if this is the best approach, > with the best performance, but it relies on delegates. > > class MyClassProxy : MyClass > { > ... > > delegate void __MyClass_DoSomething(int x); > > public override void DoSomething(int x) > { > MethodInfo m = MethodBase.GetMethodFromHandle( ldtoken method ); > InvocationImpl invocation = new InvocationImpl( this, m, new > __MyClass_DoSomething(callback__DoSomething), x ); > interceptor.Intercept( invocation ); > } > > private void callback__DoSomething(int x) > { > base.DoSomething(x); > } > } > > class InvocationImpl : IInvocation > { > public InvocationImpl( object proxy, MethodInfo m, delegate call, params > object[] args ) > { > .. > } > > public object Proceed() > { > call.DynamicInvoke( args ); > } > } > > > Yes, it works! > But before I start to code this beast we need to agree on these interfaces. > Also, can we think of something similar to interface proxies? > We're close to the first non-beta release and once this is release, change > interfaces will hurt users, and we don't want that. > > > -- > Cheers, > hammett > http://www.digitalcraftsmen.com.br/~hammett > > > > > > ------------------------------------------------------- > This SF.net email is sponsored by: IT Product Guide on ITManagersJournal > Use IT products in your business? Tell us what you think of them. Give us > Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more > http://productguide.itmanagersjournal.com/guidepromo.tmpl > _______________________________________________ > Aspectsharp-users mailing list > Asp...@li... > https://lists.sourceforge.net/lists/listinfo/aspectsharp-users > |
From: hammett <ha...@uo...> - 2004-10-23 17:29:02
|
Hello Deyan (where's you from btw?) > Why don't you simply generate something like the stuff below? I think that > if you don't use runtime reflection the execution will be measurable with > the unproxied execution, otherwise it's much slower ...: This is something to be considered. <snip> Your proposal is neat, while mine is much more like a kind of 'continuations' ability. I really don't know which one is better, but I like the idea of enveloping the method invocation (the invocation interface) I'll run some performance tests and will put the results here in a few minutes. Thanks for your support! :-) -- Cheers, hammett http://www.digitalcraftsmen.com.br/~hammett |