views:

726

answers:

3

Hi *,

I am developing an .net application which heavely depends on plugins. The application itself contains an connection to a remote server.

Recently I digged into Application domains and see them as the ideal solution for isolating the plugin code from the rest of the application.

However there is one big disadvantage which makes me unable to implement the application domains for hosting the plugins. It seems there is no way to pass an object by reference to another application domain which is needed to pass an reference to the connection object.

I was hoping someone could give me a workaround so I can pass an reference to that object.

Note: Creating a proxy is out of the question, the connection layer already acts as a proxy since the classes are auto generated.

Note2: System.AddIn can not be used as it is not available on the compact framework.

+4  A: 

Have you tried deriving from MarshalByRefObject? It's a pain in that it screws up your inheritance hierarchy, but I think it's what you want.

From the docs:

MarshalByRefObject is the base class for objects that communicate across application domain boundaries by exchanging messages using a proxy. Objects that do not inherit from MarshalByRefObject are implicitly marshal by value. When a remote application references a marshal by value object, a copy of the object is passed across application domain boundaries.

MarshalByRefObject objects are accessed directly within the boundaries of the local application domain. The first time an application in a remote application domain accesses a MarshalByRefObject, a proxy is passed to the remote application. Subsequent calls on the proxy are marshaled back to the object residing in the local application domain.

Types must inherit from MarshalByRefObject when the type is used across application domain boundaries, and the state of the object must not be copied because the members of the object are not usable outside the application domain where they were created.

In my experience, it can be pretty limiting - you really need to do as little as possible across the AppDomain boundary, preferrably restricting yourself to operations which only require primitive types, strings, and arrays of both. This may well be due to my own inexperience in working with multiple AppDomains, but it's just a warning that it's a bit of a minefield.

Jon Skeet
Darn, 18 seconds too late...
Marc Gravell
I see the way it can screw up my inheritance hierarchy.I'll check it out, thanks.
Stormenet
Well, I tried, and it looked promising.But, most of the plugins return an usercontrol that needs to be hosted in the main app and that seems really tricky :s
Stormenet
Yes, doing cross-domain user interface stuff is really hard. Have you looked at the .NET 3.5 System.AddIn stuff? I don't know whether it would be useful to you or not, but probably worth a look... http://blogs.msdn.com/zifengh/
Jon Skeet
+1  A: 

To talk to the same instance between AppDomains, it must inherit from MarshalByRefObject. Done this way, every method call to the object (including properties etc) is actually a remoting call to the other app-domain. Does that help?

Marc Gravell
A: 

Be aware that clean-up of MarshalByRefObject proxies are cleaned up based on a lease. In short if you don't use the object for a specific time it will be reclaimed. You can control this by overriding InitializeLifetimeService to return a lease object which matches you needs. If you return null you effectively disable the leasing and then the object is only reclaimed when the AppDomain is unloaded.

Brian Rasmussen