Solving the Enterprise Services config dilemma. Here's a little variation of System.EnterpriseServices.ServicedComponent that activates classes derived from ServicedComponentEx in a freely configurable, non-default app-domain and roots them in the directory of the assembly containing the component and not system32. TODO: Add support for custom config files based on COM+ package name, proper security setup, etc; Still, I am tired, so I am posting anyways ;) G'night. using System; using System.Runtime.InteropServices; using System.EnterpriseServices; using System.IO; using System.Reflection; using System.Runtime.Remoting; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Contexts; namespace newtelligence.EnterpriseServices { [AttributeUsage(AttributeTargets.Class)] public class ServicedComponentExProxyAttribute : ProxyAttribute, ICustomFactory { ProxyAttribute _base; Type currentType; static AppDomain appDomain = null;
public ServicedComponentExProxyAttribute() { _base = (ProxyAttribute)typeof(ServicedComponent).GetCustomAttributes(typeof(ProxyAttribute),false)[0]; } public override MarshalByRefObject CreateInstance(Type serverType) { return _base.CreateInstance(serverType); } public override RealProxy CreateProxy(ObjRef objRef,Type serverType,object serverObject,Context serverContext) { return _base.CreateProxy(objRef,serverType,serverObject,serverContext); } Assembly ResolveHelper(object o, ResolveEventArgs rargs) { if ( currentType.Assembly.FullName == rargs.Name ) { return Assembly.LoadFrom(currentType.Assembly.Location); } else { return null; } } MarshalByRefObject ICustomFactory.CreateInstance(Type serverType) { if ( AppDomain.CurrentDomain.FriendlyName == "myappdomain" ) { return ((ICustomFactory)_base).CreateInstance(serverType); } else { if ( appDomain == null ) { System.AppDomainSetup appDomainSetup = new AppDomainSetup(); appDomainSetup.ApplicationBase = Path.Combine(Path.GetPathRoot(serverType.Assembly.Location), Path.GetDirectoryName(serverType.Assembly.Location)); appDomainSetup.ApplicationName = "complus"; appDomain = AppDomain.CreateDomain("myappdomain",null,appDomainSetup); } ResolveEventHandler reh = new ResolveEventHandler(this.ResolveHelper); currentType = serverType; AppDomain.CurrentDomain.AssemblyResolve += reh; MarshalByRefObject mbr = (MarshalByRefObject)appDomain.CreateInstanceFromAndUnwrap( serverType.Assembly.Location,serverType.FullName); AppDomain.CurrentDomain.AssemblyResolve -= reh; currentType = null; return mbr; } } }
[ServicedComponentExProxyAttribute] public class ServicedComponentEx : ServicedComponent { public ServicedComponentEx() { } } }
12:43:43 AM
|
|