[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.remoting

Creating a Singleton that is a cross AppDomain Singleton

kevin_ferron

9/14/2004 3:01:00 PM

Creating a Singleton that is a cross AppDomain Singleton

I'd like to thank Eric Gunnerson for his article on AppDomains and
Dynamic Loading (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp05...)
for it really helped me out with the issue i was having with how to
unload assemblies.

Now, if you follow his example, check out the RemoteLoader class.. see
how he is returning the list of functions? Well what I'm trying to do
is to store all the plugin objects inside a singleton I've got running
in the main AppDomain.

Well, that doesnt work right now because I can't figure out how to
obtain an instance of an object that is running in a seperate
AppDomain.. Am I going to have to Marshal that back somehow? Does
anyone have any advice? Is trying to make a singleton that ensures one
instance cross AppDomains the wrong way for me to go? Should I be
focusing instead on customising a collection that remotes cross
process from my version of RemoteLoader?
3 Answers

Ken Kolda

9/14/2004 3:55:00 PM

0

See comments inline below...

"phool" <kevin_ferron@hotmail.com> wrote in message
news:2b2158b3.0409140700.3d893022@posting.google.com...
> Creating a Singleton that is a cross AppDomain Singleton
>
> I'd like to thank Eric Gunnerson for his article on AppDomains and
> Dynamic Loading
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/...
ml/csharp05162002.asp)
> for it really helped me out with the issue i was having with how to
> unload assemblies.
>
> Now, if you follow his example, check out the RemoteLoader class.. see
> how he is returning the list of functions? Well what I'm trying to do
> is to store all the plugin objects inside a singleton I've got running
> in the main AppDomain.

If you store the plugin objects in your main AppDomain, then you've defeated
the purpose of creating a separate AppDomain in that, even if you unload the
other AppDomain, you'll still have the plugin assemblies loaded. In order
for the plugin assemblies only to be loaded in the second AppDomain you must
be sure that your primary AppDomain never obtains a direct reference to a
method/class/type/etc. from one of those assemblies.

>
> Well, that doesnt work right now because I can't figure out how to
> obtain an instance of an object that is running in a seperate
> AppDomain..

In the sample code it demonstrates how to do this. In fact, there are two
different objects which "live" in the second AppDomain but are used by the
main AppDomain thru a proxy: the RemoteLoader and the FunctionList. Notice
that both of these object derive from MarshalByRefObject, which means when a
reference to the object crosses the AppDomain boundary, only a proxy is
created in the main AppDomain. Any method calls on the object are forwarded
to the second AppDomain and executed there.

> Am I going to have to Marshal that back somehow? Does
> anyone have any advice? Is trying to make a singleton that ensures one
> instance cross AppDomains the wrong way for me to go?

You can create a singleton to hold the plugins, but it must live in the
second AppDomain. If you wish, you can make this singleton a
MarshalByRefObject and then access it from the main AppDomain. The main
complication is in getting a reference to this object from the main
AppDomain. For that, you'd probably instantiate a class in the second
AppDomain using CreateInstanceAndUnwrap() (the way the example code creates
the RemoteLoader) and invoke a method that returns a reference to the
singleton.

> Should I be
> focusing instead on customising a collection that remotes cross
> process from my version of RemoteLoader?

The FunctionList object provided in the sample code does just this. Is there
some additional behavior you need that this isn't providing (or couldn't
just be added on to what's there)?

Ken



kevin_ferron

9/15/2004 12:04:00 AM

0

Thanks for you reply, comments inline..

> If you store the plugin objects in your main AppDomain, then you've defeated
> the purpose of creating a separate AppDomain in that, even if you unload the
> other AppDomain, you'll still have the plugin assemblies loaded. In order
> for the plugin assemblies only to be loaded in the second AppDomain you must
> be sure that your primary AppDomain never obtains a direct reference to a
> method/class/type/etc. from one of those assemblies.


Ok, this was probably the conceptual barrier i was facing.

> The FunctionList object provided in the sample code does just this. Is there
> some additional behavior you need that this isn't providing (or couldn't
> just be added on to what's there)?

Well the main difference is that in Erics example is a collection of
functions
whereas the way i have mine is that i need a collection of objects..

So am I correct that really what i want to do is be calling a proxy
class in the main AppDomain that acts as an interface to each of the
objects that im marshalling from the secondary AppDomain?


"Ken Kolda" <ken.kolda@elliemae-nospamplease.com> wrote in message news:<eA7$#MnmEHA.3172@TK2MSFTNGP10.phx.gbl>...
> See comments inline below...
>
> "phool" <kevin_ferron@hotmail.com> wrote in message
> news:2b2158b3.0409140700.3d893022@posting.google.com...
> > Creating a Singleton that is a cross AppDomain Singleton
> >
> > I'd like to thank Eric Gunnerson for his article on AppDomains and
> > Dynamic Loading
> (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/...
> ml/csharp05162002.asp)
> > for it really helped me out with the issue i was having with how to
> > unload assemblies.
> >
> > Now, if you follow his example, check out the RemoteLoader class.. see
> > how he is returning the list of functions? Well what I'm trying to do
> > is to store all the plugin objects inside a singleton I've got running
> > in the main AppDomain.
>
> If you store the plugin objects in your main AppDomain, then you've defeated
> the purpose of creating a separate AppDomain in that, even if you unload the
> other AppDomain, you'll still have the plugin assemblies loaded. In order
> for the plugin assemblies only to be loaded in the second AppDomain you must
> be sure that your primary AppDomain never obtains a direct reference to a
> method/class/type/etc. from one of those assemblies.
>
> >
> > Well, that doesnt work right now because I can't figure out how to
> > obtain an instance of an object that is running in a seperate
> > AppDomain..
>
> In the sample code it demonstrates how to do this. In fact, there are two
> different objects which "live" in the second AppDomain but are used by the
> main AppDomain thru a proxy: the RemoteLoader and the FunctionList. Notice
> that both of these object derive from MarshalByRefObject, which means when a
> reference to the object crosses the AppDomain boundary, only a proxy is
> created in the main AppDomain. Any method calls on the object are forwarded
> to the second AppDomain and executed there.
>
> > Am I going to have to Marshal that back somehow? Does
> > anyone have any advice? Is trying to make a singleton that ensures one
> > instance cross AppDomains the wrong way for me to go?
>
> You can create a singleton to hold the plugins, but it must live in the
> second AppDomain. If you wish, you can make this singleton a
> MarshalByRefObject and then access it from the main AppDomain. The main
> complication is in getting a reference to this object from the main
> AppDomain. For that, you'd probably instantiate a class in the second
> AppDomain using CreateInstanceAndUnwrap() (the way the example code creates
> the RemoteLoader) and invoke a method that returns a reference to the
> singleton.
>
> > Should I be
> > focusing instead on customising a collection that remotes cross
> > process from my version of RemoteLoader?
>
> The FunctionList object provided in the sample code does just this. Is there
> some additional behavior you need that this isn't providing (or couldn't
> just be added on to what's there)?
>
> Ken

Ken Kolda

9/15/2004 3:06:00 PM

0

What I would advise is that you create an abstract base class from which all
of yur plugin objects must derive, e.g.

public abstract class Plugin : MarshalByRefObject
{
// ... Your plugin's interface methods go here
}

This would ensure that every plugin must be a MarshalByRefObject so you
could obtain references to the plugin objects from your main AppDomain and
invoke methods on them without having them get loaded in that AppDomain.

If that's not feasible, then I'd create a wrapper class that derives from
MarshalByRefObject and implements the same interface as your plugins. The
wrapper would simply delegate calls to an internally held plugin object,
e.g.

public class PluginWrapper : MarshalByRefObject, IPlugin
{
private Plugin innerPlugin;

public PluginWrapper(Plugin plugin) { innerPlugin = plugin; }
public SomePluginMethod() { innerPlugin.SomePluginMethod(); }
}

You would then pass the wrapper back to the main AppDomain so it could
invoke the plugin methods thru the wrapper.

Hope that helps -
Ken


"phool" <kevin_ferron@hotmail.com> wrote in message
news:2b2158b3.0409141603.71bb1b3d@posting.google.com...
> Thanks for you reply, comments inline..
>
> > If you store the plugin objects in your main AppDomain, then you've
defeated
> > the purpose of creating a separate AppDomain in that, even if you unload
the
> > other AppDomain, you'll still have the plugin assemblies loaded. In
order
> > for the plugin assemblies only to be loaded in the second AppDomain you
must
> > be sure that your primary AppDomain never obtains a direct reference to
a
> > method/class/type/etc. from one of those assemblies.
>
>
> Ok, this was probably the conceptual barrier i was facing.
>
> > The FunctionList object provided in the sample code does just this. Is
there
> > some additional behavior you need that this isn't providing (or couldn't
> > just be added on to what's there)?
>
> Well the main difference is that in Erics example is a collection of
> functions
> whereas the way i have mine is that i need a collection of objects..
>
> So am I correct that really what i want to do is be calling a proxy
> class in the main AppDomain that acts as an interface to each of the
> objects that im marshalling from the secondary AppDomain?
>
>
> "Ken Kolda" <ken.kolda@elliemae-nospamplease.com> wrote in message
news:<eA7$#MnmEHA.3172@TK2MSFTNGP10.phx.gbl>...
> > See comments inline below...
> >
> > "phool" <kevin_ferron@hotmail.com> wrote in message
> > news:2b2158b3.0409140700.3d893022@posting.google.com...
> > > Creating a Singleton that is a cross AppDomain Singleton
> > >
> > > I'd like to thank Eric Gunnerson for his article on AppDomains and
> > > Dynamic Loading
> >
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/...
> > ml/csharp05162002.asp)
> > > for it really helped me out with the issue i was having with how to
> > > unload assemblies.
> > >
> > > Now, if you follow his example, check out the RemoteLoader class.. see
> > > how he is returning the list of functions? Well what I'm trying to do
> > > is to store all the plugin objects inside a singleton I've got running
> > > in the main AppDomain.
> >
> > If you store the plugin objects in your main AppDomain, then you've
defeated
> > the purpose of creating a separate AppDomain in that, even if you unload
the
> > other AppDomain, you'll still have the plugin assemblies loaded. In
order
> > for the plugin assemblies only to be loaded in the second AppDomain you
must
> > be sure that your primary AppDomain never obtains a direct reference to
a
> > method/class/type/etc. from one of those assemblies.
> >
> > >
> > > Well, that doesnt work right now because I can't figure out how to
> > > obtain an instance of an object that is running in a seperate
> > > AppDomain..
> >
> > In the sample code it demonstrates how to do this. In fact, there are
two
> > different objects which "live" in the second AppDomain but are used by
the
> > main AppDomain thru a proxy: the RemoteLoader and the FunctionList.
Notice
> > that both of these object derive from MarshalByRefObject, which means
when a
> > reference to the object crosses the AppDomain boundary, only a proxy is
> > created in the main AppDomain. Any method calls on the object are
forwarded
> > to the second AppDomain and executed there.
> >
> > > Am I going to have to Marshal that back somehow? Does
> > > anyone have any advice? Is trying to make a singleton that ensures one
> > > instance cross AppDomains the wrong way for me to go?
> >
> > You can create a singleton to hold the plugins, but it must live in the
> > second AppDomain. If you wish, you can make this singleton a
> > MarshalByRefObject and then access it from the main AppDomain. The main
> > complication is in getting a reference to this object from the main
> > AppDomain. For that, you'd probably instantiate a class in the second
> > AppDomain using CreateInstanceAndUnwrap() (the way the example code
creates
> > the RemoteLoader) and invoke a method that returns a reference to the
> > singleton.
> >
> > > Should I be
> > > focusing instead on customising a collection that remotes cross
> > > process from my version of RemoteLoader?
> >
> > The FunctionList object provided in the sample code does just this. Is
there
> > some additional behavior you need that this isn't providing (or couldn't
> > just be added on to what's there)?
> >
> > Ken