waoywssy / linfu

Automatically exported from code.google.com/p/linfu
0 stars 0 forks source link

Linfu DynamicProxy overrides GetType() method. #34

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,

I'm working on a proyect with NHibernate and LinFu, and I've found a
problem caused due to LinFu's ProxyFactory overriding GetType() method on
generated proxy.

My code is partially based on SharpArchitecture's code, which uses a base
class (BaseObject) to define domain entity classes.

At this BaseObject class there's some trick at Equals() method which allows
comparing a real object against a proxied one by calling
"GetUnproxiedType()", which calls "GetType()" from whithin base class
instead of from the finall one (the one being proxied by NH).

You can see the details here: (Look for Equals() and GetTypeUnproxied())
http://code.google.com/p/sharp-architecture/source/browse/trunk/src/SharpArch/Sh
arpArch.Core/DomainModel/BaseObject.cs

The point is that this code is working fine with NHibernate+Castle, but
fails with NHibernate+LinFu.

Is this an expected behaviour? Is there any workaround?

Thnks in advice.

Original issue reported on code.google.com by pablo.r...@gmail.com on 20 Aug 2009 at 8:37

GoogleCodeExporter commented 9 years ago
Hi Pablo,

Yes, this is the expected behavior for LinFu.DynamicProxy. You can work around 
it by
returning the actual object type in the intercepted GetType() call.

Original comment by Philip.L...@gmail.com on 20 Aug 2009 at 9:29

GoogleCodeExporter commented 9 years ago
After analyzing the problem, it seems related to the fact that LinFu it's not 
caching
the generated Type it creates under the hood to instantiate the proxy..

So my two instances, even if both of them are proxy's, aren't of the same type.

Is this also, by design?

Original comment by pablo.r...@gmail.com on 20 Aug 2009 at 11:15

GoogleCodeExporter commented 9 years ago
This is the code i'm using:

public class Class 
{
    public string Property { get; set; }
}

public class Interceptor : IInterceptor  
{  
    public object Intercept(InvocationInfo info)  
    {  
        return info.TargetMethod.Invoke(info.TargetMethod, info.Arguments);  
    }  
}

void Main()
{
    var obj1 = new Class();
    var obj2 = (Class)new ProxyFactory().CreateProxy(typeof(Class), new Interceptor(),
new Type[] {});
    var obj3 = (Class)new ProxyFactory().CreateProxy(typeof(Class), new Interceptor(),
new Type[] {});

    obj1.GetType().Dump("Obj1");
    obj2.GetType().Dump("Obj2");
    obj3.GetType().Dump("Obj3");

    (obj1.Equals(obj2)).Dump(); // Returns false
    (obj1.GetType() == obj2.GetType()).Dump(); // Returns false

    (obj1.Equals(obj3)).Dump(); // Returns false
    (obj1.GetType() == obj3.GetType()).Dump(); // Returns false

    (obj2.Equals(obj3)).Dump(); // Returns false
    (obj2.GetType() == obj3.GetType()).Dump(); // Returns true

}

Original comment by pablo.r...@gmail.com on 20 Aug 2009 at 11:29

GoogleCodeExporter commented 9 years ago
Try:

var firstFactory = new ProxyFactory();
var secondFactory = new ProxyFactory();

var isSameType = firstFactory.CreateProxyType(typeof(Class)) ==
secondFactory.CreateProxyType(typeof(Class));

Is the isSameType variable true, or false? If it's true, that means the proxy 
caches
types correctly. If it's false, then we definitely have a bug here

Original comment by Philip.L...@gmail.com on 20 Aug 2009 at 11:51

GoogleCodeExporter commented 9 years ago
It's true.. definitly the error is _not_ at linfu.

On new tests i've just made, I found NHibernate to behave differently when using
LinFu, vs (Castle|Spring).

I'm trying to isolate my case with as few code as possible.. But right now, it 
is
clear that with castle or spring it it's always generating proxies for my lazy 
objects. 
But when it comes to LinFu, it does not always generate proxy instances.. So, 
at some
point a comparison between a proxy and a non-proxy is done.. and everything 
blows away...

Anyway, thank you very much for you help... and for your product (linfu).

I will go to blame (joke) nhibernate guys..

Original comment by pablo.r...@gmail.com on 21 Aug 2009 at 12:15

GoogleCodeExporter commented 9 years ago

Original comment by Philip.L...@gmail.com on 21 Aug 2009 at 1:11

GoogleCodeExporter commented 9 years ago
Hi, after analyzing the problen in depth, I found it to be a diferent behavior
between castle, spring and Linfu.

Seems like LinFu (or the way NH is calling LinFu) does not override protected
properties/members.

I've assembled a piece of code with relays on NH and compares the behaviour of
castle, spring and linfu's proxy factories.

What I've found can be read here:
http://nhjira.koah.net/browse/NH-1937?page=com.atlassian.jira.plugin.system.issu
etabpanels:comment-tabpanel

However, I've not found documentation enough on howto override such behavior 
while
instantiating a LinFu proxy.

Can you help me on this subject?

Thanks.

Original comment by pablo.r...@gmail.com on 24 Aug 2009 at 12:50

GoogleCodeExporter commented 9 years ago
LinFu.DynamicProxy v1.0 doesn't proxy protected/protected internal methods and
properties, but that has been fixed with LinFu.Proxy (aka LinFu.DP2). Dario 
Quintana
wrote an bytecode provider for the LinFu.Proxy and it passed all the NH tests, 
but
I'm not sure if the NH team added LinFu.Proxy to the latest release of NH. You 
might
want to check with them and see what happened with that.

Original comment by Philip.L...@gmail.com on 27 Aug 2009 at 11:35