Custom marshalling

  • Thread starter Thread starter Bjarke Lindberg
  • Start date Start date
B

Bjarke Lindberg

Hey NG.

Using .NET remoting it's possible to "override" the <c>new</c> operator
to return a proxy to the object in question.

I'd like to use this approach to let a factory class return the
reference to the newly created object instead of letting the runtime
instantiate the object.

Does anybody know any references for doing this? (If it's possible at
all). Any feedback would be appriciated.

Thanks,
Bjarke
 
just preparing for 70-320 so i will try and answer some questions.

if you remotable class inherits from MarshalByRefernce then when a client
tries to instantiate it... all they get is the proxy object.
the only thing is that remoting runtime instantiates the object. you can set
the mode to either client activated CAO... ie the lifetime on server is
determined by the client
or server activated SAO... in which case you can either have a single call
or a singleton implementation.

you can also choose to use a custom class factory which is a SAO and a
method will return the remotable object as client activated

more of this one
http://msdn.microsoft.com/library/d...-us/cpguide/html/cpconnetremotingoverview.asp

--

Regards,

Hermit Dave
(http://hdave.blogspot.com)
 
Hey Hermit..

Hermit said:
if you remotable class inherits from MarshalByRefernce then when a client
tries to instantiate it... all they get is the proxy object.

Right. And that is what my question is about. I know about remoting and
I know my (GOF) patterns - that's why I figured that it should be
possible to do what I initially asked. Maybe I wasn't clear enough, when
asking so I'll try again.

I need a way to make the runtime use a factory when creating a new
instance of a class. Like the remoting runtime is creating a new proxy,
and returning the reference to this, when you're using the <c>new</c>
operator on a class. (On a Client Activated Object)

For instance - I'm creating a framework. This framework have a factory
class which should/could be used to create instances of a class in this
framework. This means - everyone outsite the framework should use this
factory class when creating new instances and I could mark the
constructor of the classes as <c>internal</c>.

Anyway - wouldn't it be elegant if the user of the framework could just
create a new instance using <code>MyClass myClass = new MyClass()</code>
and then the .NET runtime would intercept the call and returning a
reference created by the factory? - Remoting is using this "feature"
when creating CAO's - and my question is - is it possible to plug
in/implement some type of custom marshaler and make this happen seamless
for the user of the framework?

/B.asking
 
well the way it currently works is that you get a proxy to the class factory
and then use a method on class factory to create an instance of the desired
CAO.
if your CAO has two constructor then write two methods on Class Factory or
overload the method.

for your users to just use
MyClass myClassInstance = new MyClass()
you need the objects to in the current namespace declaration. Unfortunately
with remoting objects they are not. I am not aware of hijacking the 'new'
keyword in .net framework (reminds me of something COM+ does - it hijacks
the call before delegating it to COM SCM.)

another thing if you make the classes as internal your users wont be able to
use the 'new' keyword.

CAOs with class factorys have a implementation similar to a Singleton in the
way that you have to call a method to get a instance. With singletons its
Static method of the Class with class factory. With remoting you execute a
public method or a property.

--

Regards,

Hermit Dave
(http://hdave.blogspot.com)
 
Hermit said:
for your users to just use
MyClass myClassInstance = new MyClass()
you need the objects to in the current namespace declaration.

Well - my intention wasn't to use remoting, but the same strategy as it
use to "hijack" the <c>new</c> operator. It doesn't seems to be
documented anywhere - maybe I could try to look into the mono sources
and see how they managed to do it there (if it's implemented).

Thanks for your response.

/Bjarke
 
good luck with that... you should get the mono source... alternatively you
look search around using rotor. MS implementation would be closer to the one
in Rotor than in mono.

--

Regards,

Hermit Dave
(http://hdave.blogspot.com)
 
Bjarke Lindberg said:
Hey NG.

Using .NET remoting it's possible to "override" the <c>new</c> operator to
return a proxy to the object in question.

I'd like to use this approach to let a factory class return the reference
to the newly created object instead of letting the runtime instantiate the
object.

Does anybody know any references for doing this? (If it's possible at
all). Any feedback would be appriciated.

Can you apply a custom attribute to that class? Then it's quite easy (see
code below).

Niki

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Security.Permissions;
using System.Runtime.Remoting.Contexts;

[AttributeUsage(AttributeTargets.Class)]
[SecurityPermissionAttribute(SecurityAction.Demand,
Flags=SecurityPermissionFlag.Infrastructure)]
public class MyProxyAttribute : ProxyAttribute
{
public override MarshalByRefObject CreateInstance(Type serverType)
{
if (serverType == typeof(CustomServer))
return new DerivedClass();
else
return base.CreateInstance(serverType);
}
}

[MyProxyAttribute]
public class CustomServer : ContextBoundObject
{
public virtual void HelloMethod()
{
Console.WriteLine("Base method");
}
}

public class DerivedClass : CustomServer
{
public override void HelloMethod()
{
Console.WriteLine("Been derived!");
}
}

class Test
{
static void Main()
{
CustomServer x = new CustomServer();
x.HelloMethod();
}
}
 
Niki Estner said:
Can you apply a custom attribute to that class? Then it's quite easy (see
code below).

The code I posted before always returned a transparent proxy; The only way
I've found to create the real object without a proxy was using an
undocumented function from RemotingServices.

Niki

using System;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Security.Permissions;

[AttributeUsage(AttributeTargets.Class)]
[SecurityPermissionAttribute(SecurityAction.Demand,
Flags=SecurityPermissionFlag.Infrastructure)]
public class MyProxyAttribute : ProxyAttribute
{
public override MarshalByRefObject CreateInstance(Type serverType)
{
if (serverType == typeof(CustomServer))
{
DerivedClass d = new DerivedClass();
return d;
}
else
{
MethodInfo mi =
typeof(RemotingServices).GetMethod("AllocateInitializedObject",
BindingFlags.Static|BindingFlags.NonPublic, null, new Type[] {
typeof(Type) }, null);
object o = mi.Invoke(null, new object[] { typeof(DerivedClass) });
return (MarshalByRefObject)o;
}
}
}


[MyProxyAttribute]
public class CustomServer : ContextBoundObject
{
public virtual void HelloMethod()
{
Console.WriteLine("Base method");
}
}

public class DerivedClass : CustomServer
{
public override void HelloMethod()
{
Console.WriteLine("Been derived!");
}
}

class Test
{
static unsafe void Main()
{
CustomServer x = new CustomServer();
x.HelloMethod();
}
}
 
Niki said:
The code I posted before always returned a transparent proxy; The only way
I've found to create the real object without a proxy was using an
undocumented function from RemotingServices.

Thanks Niki! You've saved my day! :)

/Bjarke
 
Back
Top