So, the situation is that we have a poorly-executed UserControl that relies on a number of singletons in its assembly that unfortunately, over time, began acquiring the state of the control. Therefore, among other problems, we now can't have more than one instance of this control in a given application.
Obviously, refactoring to move the state in question back where it belongs is the most desirable choice, but we're also exploring other options that wouldn't cause so many ripples in our codebase (meaning, time-consuming refactoring, retesting, redeployment, etc.).
Two possibilities that seemed hopeful were to instantiate the control in question in either (a) subordinate AppDomains within our application or (b) out-of-process COM+ servers installed on the same machine (colocated). In both cases, factories would be obtained from the client application that would issue the control at runtime, and the static data (unfortunately) related to each instance would be isolated.
Designing both of these was very simple -- AppDomains and out-of-process COM+ servers are dead easy in C#/.NET -- but in both cases we get back proxy objects (different variants, but still .NET proxies) that we can't add to a control container in the client application, whether or not do it in the UI thread (via Control.Invoke).
In the case of the AppDomain approach, non-serializable fields, such as "Parent", don't appear to be exposed through the proxy so it's basically unusable. In the case of the out-of-process ("Server") COM+ server the UserControl comes back but isn't add-able with the following exception:
"...An unhandled exception of
type 'System.Runtime.Remoting.RemotingException' occurred
in mscorlib.dll
Additional information: This remoting proxy has no
channel sink which means either the server has no
registered server channels that are listening, or this
application has no suitable client channel to talk to the
server..."
...now, from the little that I have read about event sinks, it seems plausible that I could wire up one or more event shims and get this to work, but am I just wrapped around the axle here? I can't believe this should be that complicated, so I've come to the conclusion that I'm just missing another, better approach to this problem.
There are other things that have occurred to us, for example using thread-local keys to cause singleton accessors to deal out instances rather than one instance, but these "singletons" are both nested and numerous, so it's not nearly as simple as it sounds -- more productive to refactor correctly at that point.
I look forward to your responses, and please let me know if I may provide any additional information.