vb.net - How do you return an object as the return value through a RealProxy transparent proxy? -


i'm working system plan on using realproxy objects enable intercepting method calls against set of objects, handling call, , returning appropriate results.

this works find simple return types strings or ints, can't seem return objects realproxy.invoke method.

everything works. no errors, returned value nothing, instead of object.

i've worked smallest sample code could, , have included below.

essentially, call rptest , single step through. code creates simple object, rptesta, string field , object valued field retrieves string dim x = c.name works fine , attempts retrieve object

dim r = c.subobj 

which returns nothing.

however, in fieldgetter routine, code:

'---- field object type field   dim mc = new methodcallmessagewrapper(msg)    '---- create object   dim o = activator.createinstance(t)   '---- , construct return message object   dim r = new returnmessage(o, mc.args, mc.args.length, mc.logicalcallcontext, mc)   return r   

appears work fine, setting returnvalue field of returnmessage object created activator.createinstance(t) call above.

i suspect it's serialization thing of sort, i'm @ loss.

you should able run code straight away, pasting new vb.net project.

'---------------------------------------------------------------------------- imports system.security.permissions imports system.diagnostics imports system.reflection imports system.runtime.compilerservices imports system.runtime.serialization imports system.runtime.remoting imports system.runtime.remoting.activation imports system.runtime.remoting.messaging imports system.runtime.remoting.proxies   public module rptest     public sub rptest()         '---- create new object automatically proxied         '     see rpproxyattribute details         dim c = new rptesta          dim x = c.name         'x returned string value fine         dim r = c.subobj         '********* problem here, r ends nothing     end sub end module   'root test object public class rptesta     inherits rpbase      public name string = "test name"     public subobj rptestb  end class   'sub object should returned field value root object above public class rptestb     inherits rpbase      public subproperty string = "subobj test property" end class   ''' <summary> ''' base proxyable object class ''' </summary> ''' <remarks></remarks> <rpproxy()> _ public mustinherit class rpbase     inherits contextboundobject  end class   <permissionset(securityaction.demand, name:="fulltrust")> _ public class rpproxy     inherits realproxy      private m_target marshalbyrefobject       public sub new()         m_target = directcast(activator.createinstance(gettype(configrp)), marshalbyrefobject)         dim myobjref = remotingservices.marshal(m_target)     end sub      public sub new(byval classtoproxy type)         mybase.new(classtoproxy)     end sub       public sub new(byval classtoproxy type, byval targetobject marshalbyrefobject)         m_target = targetobject         dim myobjref = remotingservices.marshal(m_target)     end sub       public overrides function invoke(byval msg imessage) imessage         dim returnmsg imethodreturnmessage = nothing          if typeof msg iconstructioncallmessage             '---- handle constructor calls             dim constructioncallmessage = directcast(msg, iconstructioncallmessage)             returnmsg = initializeserverobject(constructioncallmessage)             me.m_target = me.getunwrappedserver()             setstubdata(me, me.m_target)             return returnmsg          elseif typeof msg imethodcallmessage             '---- handle other method calls             dim methodcallmessage = directcast(msg, imethodcallmessage)              '---- before message processing             preprocess(methodcallmessage)              '---- execute method call             dim rawreturnmessage = remotingservices.executemessage(me.m_target, methodcallmessage)              '---- , postprocess             returnmsg = postprocess(methodcallmessage, rawreturnmessage)          else             throw new notsupportedexception()         end if          return returnmsg     end function       'called before actual method invoked     private sub preprocess(byval msg imessage)         console.writeline("before method call...")     end sub       'called after actual method invoked     private function postprocess(byval msg imethodcallmessage, byval msgreturn returnmessage) returnmessage         dim r returnmessage         if msg.methodname = "fieldgetter"             r = fieldgetter(msg, msgreturn)         elseif msg.methodname = "fieldsetter"             'na             r = msgreturn         elseif msg.methodname.startswith("get_")             'na             r = msgreturn         elseif msg.methodname.startswith("set_")             'na             r = msgreturn         else             r = msgreturn         end if         return r     end function       private function fieldgetter(byval msg imethodcallmessage, byval msgreturn imethodreturnmessage) imethodreturnmessage         dim t = me.target.gettype          '---- retrieves type of field getter should retrieve         t = t.getfield(msg.inargs(1), bindingflags.instance or bindingflags.public).fieldtype          if t.name = "string"             '---- return object returned result of executemessage             return msgreturn          elseif t.basetype.equals(gettype(rpbase))             '---- field object type field             dim mc = new methodcallmessagewrapper(msg)             '---- create object             dim o = activator.createinstance(t)             '---- , construct return message object             dim r = new returnmessage(o, mc.args, mc.args.length, mc.logicalcallcontext, mc)             return r          else             return msgreturn         end if     end function       public property target() object                     return me.m_target         end         set(byval value object)             me.m_target = value         end set     end property end class   <attributeusage(attributetargets.class)> _ <securitypermissionattribute(securityaction.demand, flags:=securitypermissionflag.infrastructure)> _ public class rpproxyattribute     inherits proxyattribute       public overrides function createinstance(byval type type) marshalbyrefobject         dim proxy = new rpproxy(type)         dim transparentproxy = directcast(proxy.gettransparentproxy(), marshalbyrefobject)         return transparentproxy     end function end class 

well, turns out pretty simple fix, once work past god awful returnmessage constructor that's quite misleading!

many old colleague of mine, rich quackenbush, taking few minutes , checking out. sometimes, can't see forest trees!

anyway, in fieldgetter, doing this

elseif t.basetype.equals(gettype(rpbase))         '---- field object type field         dim mc = new methodcallmessagewrapper(msg)         '---- create object         dim o = activator.createinstance(t)         '---- , construct return message object         dim r = new returnmessage(o, mc.args, mc.args.length, mc.logicalcallcontext, mc)         return r 

seems reasonable, newly created object being passed returnmessage constructor argument called returnvalue.

but no. have create object array , pass 3 element in array, this:

elseif t.basetype.equals(gettype(rpbase))         '---- field object type field         dim mc = new methodcallmessagewrapper(msg)            '---- create object         dim o = activator.createinstance(t)         '---- , construct return message object         dim r = new returnmessage(nothing, new object() {nothing, nothing, o}, 3, mc.logicalcallcontext, mc)         return r 

it turns out, because fieldgetter function in being "called" , intercepted proxy, , it's signature is

fieldgetter(stringtypename,stringfieldname,object&val) 

which, purposes of constructing returnmessage call means doesn't have returnvalue @ all, rather return value returned 3'rd argument in list.

since i'm not calling real fieldgetter function, first 2 argument (the typename , fieldname) immaterial, 3'rd argument proper place put return value.

it's obvious in hindsight!

many rich.


Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -