2 // System.Runtime.Remoting.RemotingConfiguration.cs
4 // Author: Jaime Anguiano Olarra (jaime@gnome.org)
5 // Lluis Sanchez Gual (lluis@ideary.com)
7 // (C) 2002, Jaime Anguiano Olarra
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System
.Reflection
;
36 using System
.Collections
;
37 using System
.Runtime
.Remoting
.Activation
;
38 using System
.Runtime
.Remoting
.Channels
;
39 using System
.Runtime
.Remoting
.Lifetime
;
42 namespace System
.Runtime
.Remoting
44 public class RemotingConfiguration
47 // Private constructor: nobody instantiates this.
49 private RemotingConfiguration ()
53 static string applicationID
= null;
54 static string applicationName
= null;
55 static string configFile
= "";
56 static MiniParser parser
= null;
57 static string processGuid
= null;
58 static bool defaultConfigRead
= false;
59 static bool defaultDelayedConfigRead
= false;
60 static string _errorMode
;
62 static Hashtable wellKnownClientEntries
= new Hashtable();
63 static Hashtable activatedClientEntries
= new Hashtable();
64 static Hashtable wellKnownServiceEntries
= new Hashtable();
65 static Hashtable activatedServiceEntries
= new Hashtable();
67 static Hashtable channelTemplates
= new Hashtable ();
68 static Hashtable clientProviderTemplates
= new Hashtable ();
69 static Hashtable serverProviderTemplates
= new Hashtable ();
72 // At this time the ID will be the application name
73 public static string ApplicationId
77 applicationID
= AppDomain
.CurrentDomain
.SetupInformation
.ApplicationName
;
82 public static string ApplicationName
86 applicationName
= AppDomain
.CurrentDomain
.SetupInformation
.ApplicationName
;
91 // We return null if the application name has not been set.
94 set { applicationName = value; }
97 public static string ProcessId
100 if (processGuid
== null)
101 processGuid
= AppDomain
.GetProcessGuid ();
110 public static void Configure (string filename
)
112 lock (channelTemplates
)
114 if (!defaultConfigRead
)
116 ReadConfigFile (Environment
.GetMachineConfigPath ());
117 defaultConfigRead
= true;
120 if (filename
!= null)
121 ReadConfigFile (filename
);
125 private static void ReadConfigFile (string filename
)
129 MiniParser parser
= new MiniParser ();
130 RReader rreader
= new RReader (filename
);
131 ConfigHandler handler
= new ConfigHandler (false);
132 parser
.Parse (rreader
, handler
);
136 throw new RemotingException ("Configuration file '" + filename
+ "' could not be loaded: " + ex
.Message
);
140 internal static void LoadDefaultDelayedChannels ()
142 lock (channelTemplates
)
144 if (defaultDelayedConfigRead
|| defaultConfigRead
) return;
146 MiniParser parser
= new MiniParser ();
147 RReader rreader
= new RReader (Environment
.GetMachineConfigPath ());
148 ConfigHandler handler
= new ConfigHandler (true);
149 parser
.Parse (rreader
, handler
);
150 defaultDelayedConfigRead
= true;
154 public static ActivatedClientTypeEntry
[] GetRegisteredActivatedClientTypes ()
156 lock (channelTemplates
)
158 ActivatedClientTypeEntry
[] entries
= new ActivatedClientTypeEntry
[activatedClientEntries
.Count
];
159 activatedClientEntries
.Values
.CopyTo (entries
,0);
164 public static ActivatedServiceTypeEntry
[] GetRegisteredActivatedServiceTypes ()
166 lock (channelTemplates
)
168 ActivatedServiceTypeEntry
[] entries
= new ActivatedServiceTypeEntry
[activatedServiceEntries
.Count
];
169 activatedServiceEntries
.Values
.CopyTo (entries
,0);
174 public static WellKnownClientTypeEntry
[] GetRegisteredWellKnownClientTypes ()
176 lock (channelTemplates
)
178 WellKnownClientTypeEntry
[] entries
= new WellKnownClientTypeEntry
[wellKnownClientEntries
.Count
];
179 wellKnownClientEntries
.Values
.CopyTo (entries
,0);
184 public static WellKnownServiceTypeEntry
[] GetRegisteredWellKnownServiceTypes ()
186 lock (channelTemplates
)
188 WellKnownServiceTypeEntry
[] entries
= new WellKnownServiceTypeEntry
[wellKnownServiceEntries
.Count
];
189 wellKnownServiceEntries
.Values
.CopyTo (entries
,0);
194 public static bool IsActivationAllowed (Type serverType
)
196 lock (channelTemplates
)
198 return activatedServiceEntries
.ContainsKey (serverType
);
202 public static ActivatedClientTypeEntry
IsRemotelyActivatedClientType (Type serviceType
)
204 lock (channelTemplates
)
206 return activatedClientEntries
[serviceType
] as ActivatedClientTypeEntry
;
210 public static ActivatedClientTypeEntry
IsRemotelyActivatedClientType (string typeName
, string assemblyName
)
212 return IsRemotelyActivatedClientType (Assembly
.Load(assemblyName
).GetType (typeName
));
215 public static WellKnownClientTypeEntry
IsWellKnownClientType (Type serviceType
)
217 lock (channelTemplates
)
219 return wellKnownClientEntries
[serviceType
] as WellKnownClientTypeEntry
;
223 public static WellKnownClientTypeEntry
IsWellKnownClientType (string typeName
, string assemblyName
)
225 return IsWellKnownClientType (Assembly
.Load(assemblyName
).GetType (typeName
));
228 public static void RegisterActivatedClientType (ActivatedClientTypeEntry entry
)
230 lock (channelTemplates
)
232 if (wellKnownClientEntries
.ContainsKey (entry
.ObjectType
) || activatedClientEntries
.ContainsKey (entry
.ObjectType
))
233 throw new RemotingException ("Attempt to redirect activation of type '" + entry
.ObjectType
.FullName
+ "' which is already redirected.");
235 activatedClientEntries
[entry
.ObjectType
] = entry
;
236 ActivationServices
.EnableProxyActivation (entry
.ObjectType
, true);
240 public static void RegisterActivatedClientType (Type type
, string appUrl
)
242 if (type
== null) throw new ArgumentNullException ("type");
243 if (appUrl
== null) throw new ArgumentNullException ("appUrl");
245 RegisterActivatedClientType (new ActivatedClientTypeEntry (type
, appUrl
));
248 public static void RegisterActivatedServiceType (ActivatedServiceTypeEntry entry
)
250 lock (channelTemplates
)
252 activatedServiceEntries
.Add (entry
.ObjectType
, entry
);
256 public static void RegisterActivatedServiceType (Type type
)
258 RegisterActivatedServiceType (new ActivatedServiceTypeEntry (type
));
261 public static void RegisterWellKnownClientType (Type type
, string objectUrl
)
263 if (type
== null) throw new ArgumentNullException ("type");
264 if (objectUrl
== null) throw new ArgumentNullException ("objectUrl");
266 RegisterWellKnownClientType (new WellKnownClientTypeEntry (type
, objectUrl
));
269 public static void RegisterWellKnownClientType (WellKnownClientTypeEntry entry
)
271 lock (channelTemplates
)
273 if (wellKnownClientEntries
.ContainsKey (entry
.ObjectType
) || activatedClientEntries
.ContainsKey (entry
.ObjectType
))
274 throw new RemotingException ("Attempt to redirect activation of type '" + entry
.ObjectType
.FullName
+ "' which is already redirected.");
276 wellKnownClientEntries
[entry
.ObjectType
] = entry
;
277 ActivationServices
.EnableProxyActivation (entry
.ObjectType
, true);
281 public static void RegisterWellKnownServiceType (Type type
, string objectUrl
, WellKnownObjectMode mode
)
283 RegisterWellKnownServiceType (new WellKnownServiceTypeEntry (type
, objectUrl
, mode
));
286 public static void RegisterWellKnownServiceType (WellKnownServiceTypeEntry entry
)
288 lock (channelTemplates
)
290 wellKnownServiceEntries
[entry
.ObjectUri
] = entry
;
291 RemotingServices
.CreateWellKnownServerIdentity (entry
.ObjectType
, entry
.ObjectUri
, entry
.Mode
);
295 internal static void RegisterChannelTemplate (ChannelData channel
)
297 channelTemplates
[channel
.Id
] = channel
;
300 internal static void RegisterClientProviderTemplate (ProviderData prov
)
302 clientProviderTemplates
[prov
.Id
] = prov
;
305 internal static void RegisterServerProviderTemplate (ProviderData prov
)
307 serverProviderTemplates
[prov
.Id
] = prov
;
310 internal static void RegisterChannels (ArrayList channels
, bool onlyDelayed
)
312 foreach (ChannelData channel
in channels
)
314 if (onlyDelayed
&& channel
.DelayLoadAsClientChannel
!= "true")
317 if (defaultDelayedConfigRead
&& channel
.DelayLoadAsClientChannel
== "true")
320 if (channel
.Ref
!= null)
322 ChannelData template
= (ChannelData
) channelTemplates
[channel
.Ref
];
323 if (template
== null) throw new RemotingException ("Channel template '" + channel
.Ref
+ "' not found");
324 channel
.CopyFrom (template
);
327 foreach (ProviderData prov
in channel
.ServerProviders
)
329 if (prov
.Ref
!= null)
331 ProviderData template
= (ProviderData
) serverProviderTemplates
[prov
.Ref
];
332 if (template
== null) throw new RemotingException ("Provider template '" + prov
.Ref
+ "' not found");
333 prov
.CopyFrom (template
);
337 foreach (ProviderData prov
in channel
.ClientProviders
)
339 if (prov
.Ref
!= null)
341 ProviderData template
= (ProviderData
) clientProviderTemplates
[prov
.Ref
];
342 if (template
== null) throw new RemotingException ("Provider template '" + prov
.Ref
+ "' not found");
343 prov
.CopyFrom (template
);
347 ChannelServices
.RegisterChannelConfig (channel
);
351 internal static void RegisterTypes (ArrayList types
)
353 foreach (TypeEntry type
in types
)
355 if (type
is ActivatedClientTypeEntry
)
356 RegisterActivatedClientType ((ActivatedClientTypeEntry
)type
);
357 else if (type
is ActivatedServiceTypeEntry
)
358 RegisterActivatedServiceType ((ActivatedServiceTypeEntry
)type
);
359 else if (type
is WellKnownClientTypeEntry
)
360 RegisterWellKnownClientType ((WellKnownClientTypeEntry
)type
);
361 else if (type
is WellKnownServiceTypeEntry
)
362 RegisterWellKnownServiceType ((WellKnownServiceTypeEntry
)type
);
367 public static bool CustomErrorsEnabled (bool isLocalRequest
)
369 if (_errorMode
== "off") return false;
370 if (_errorMode
== "on") return true;
371 return !isLocalRequest
;
375 internal static void SetCustomErrorsMode (string mode
)
377 if (mode
!= "on" && mode
!= "off" && mode
!= "remoteOnly")
378 throw new RemotingException ("Invalid custom error mode: " + mode
);
384 /***************************************************************
385 * Internal classes used by RemotingConfiguration.Configure () *
386 ***************************************************************/
388 internal class RReader
: MiniParser
.IReader
{
389 private string xml
; // custom remoting config file
392 public RReader (string filename
)
395 StreamReader sr
= new StreamReader (filename
);
396 xml
= sr
.ReadToEnd ();
406 return (int) xml
[pos
++];
414 internal class ConfigHandler
: MiniParser
.IHandler
416 ArrayList typeEntries
= new ArrayList ();
417 ArrayList channelInstances
= new ArrayList ();
419 ChannelData currentChannel
= null;
420 Stack currentProviderData
= null;
422 string currentClientUrl
= null;
425 string currentXmlPath
= "";
426 bool onlyDelayedChannels
;
428 public ConfigHandler (bool onlyDelayedChannels
)
430 this.onlyDelayedChannels
= onlyDelayedChannels
;
433 void ValidatePath (string element
, params string[] paths
)
435 foreach (string path
in paths
)
436 if (CheckPath (path
)) return;
438 throw new RemotingException ("Element " + element
+ " not allowed in this context");
441 bool CheckPath (string path
)
443 if (path
.StartsWith ("/"))
444 return path
== currentXmlPath
;
446 return currentXmlPath
.EndsWith (path
);
449 public void OnStartParsing (MiniParser parser
) {}
451 public void OnStartElement (string name
, MiniParser
.IAttrList attrs
)
455 if (currentXmlPath
.StartsWith ("/configuration/system.runtime.remoting"))
456 ParseElement (name
, attrs
);
458 currentXmlPath
+= "/" + name
;
462 throw new RemotingException ("Error in element " + name
+ ": " + ex
.Message
);
466 public void ParseElement (string name
, MiniParser
.IAttrList attrs
)
468 if (currentProviderData
!= null)
470 ReadCustomProviderData (name
, attrs
);
477 ValidatePath (name
, "system.runtime.remoting");
478 if (attrs
.Names
.Length
> 0)
479 appName
= attrs
.Values
[0];
483 ValidatePath (name
, "application");
484 ReadLifetine (attrs
);
488 ValidatePath (name
, "system.runtime.remoting", "application");
492 ValidatePath (name
, "channels");
493 if (currentXmlPath
.IndexOf ("application") != -1)
494 ReadChannel (attrs
, false);
496 ReadChannel (attrs
, true);
499 case "serverProviders":
500 ValidatePath (name
, "channelSinkProviders", "channel");
503 case "clientProviders":
504 ValidatePath (name
, "channelSinkProviders", "channel");
511 if (CheckPath ("application/channels/channel/serverProviders") ||
512 CheckPath ("channels/channel/serverProviders"))
514 prov
= ReadProvider (name
, attrs
, false);
515 currentChannel
.ServerProviders
.Add (prov
);
517 else if (CheckPath ("application/channels/channel/clientProviders") ||
518 CheckPath ("channels/channel/clientProviders"))
520 prov
= ReadProvider (name
, attrs
, false);
521 currentChannel
.ClientProviders
.Add (prov
);
523 else if (CheckPath ("channelSinkProviders/serverProviders"))
525 prov
= ReadProvider (name
, attrs
, true);
526 RemotingConfiguration
.RegisterServerProviderTemplate (prov
);
528 else if (CheckPath ("channelSinkProviders/clientProviders"))
530 prov
= ReadProvider (name
, attrs
, true);
531 RemotingConfiguration
.RegisterClientProviderTemplate (prov
);
538 ValidatePath (name
, "application");
539 currentClientUrl
= attrs
.GetValue ("url");
543 ValidatePath (name
, "application");
547 ValidatePath (name
, "client", "service");
548 if (CheckPath ("client"))
549 ReadClientWellKnown (attrs
);
551 ReadServiceWellKnown (attrs
);
555 ValidatePath (name
, "client", "service");
556 if (CheckPath ("client"))
557 ReadClientActivated (attrs
);
559 ReadServiceActivated (attrs
);
563 ValidatePath (name
, "application");
566 case "interopXmlType":
567 ValidatePath (name
, "soapInterop");
568 ReadInteropXml (attrs
, false);
571 case "interopXmlElement":
572 ValidatePath (name
, "soapInterop");
573 ReadInteropXml (attrs
, false);
577 ValidatePath (name
, "soapInterop");
582 ValidatePath (name
, "system.runtime.remoting");
585 case "channelSinkProviders":
586 ValidatePath (name
, "system.runtime.remoting");
590 ValidatePath (name
, "system.runtime.remoting");
591 RemotingConfiguration
.SetCustomErrorsMode (attrs
.GetValue ("mode"));
595 throw new RemotingException ("Element '" + name
+ "' is not valid in system.remoting.configuration section");
599 public void OnEndElement (string name
)
601 if (currentProviderData
!= null)
603 currentProviderData
.Pop ();
604 if (currentProviderData
.Count
> 0) return;
605 currentProviderData
= null;
608 currentXmlPath
= currentXmlPath
.Substring (0, currentXmlPath
.Length
- name
.Length
- 1);
611 void ReadCustomProviderData (string name
, MiniParser
.IAttrList attrs
)
613 SinkProviderData parent
= (SinkProviderData
) currentProviderData
.Peek ();
615 SinkProviderData data
= new SinkProviderData (name
);
616 for (int i
=0; i
< attrs
.Names
.Length
; ++i
)
617 data
.Properties
[attrs
.Names
[i
]] = attrs
.GetValue (i
);
619 parent
.Children
.Add (data
);
620 currentProviderData
.Push (data
);
623 void ReadLifetine (MiniParser
.IAttrList attrs
)
625 for (int i
=0; i
< attrs
.Names
.Length
; ++i
) {
626 switch (attrs
.Names
[i
]) {
628 LifetimeServices
.LeaseTime
= ParseTime (attrs
.GetValue(i
));
630 case "sponsorshipTimeout":
631 LifetimeServices
.SponsorshipTimeout
= ParseTime (attrs
.GetValue(i
));
633 case "renewOnCallTime":
634 LifetimeServices
.RenewOnCallTime
= ParseTime (attrs
.GetValue(i
));
636 case "leaseManagerPollTime":
637 LifetimeServices
.LeaseManagerPollTime
= ParseTime (attrs
.GetValue(i
));
640 throw new RemotingException ("Invalid attribute: " + attrs
.Names
[i
]);
645 TimeSpan
ParseTime (string s
)
647 if (s
== "" || s
== null) throw new RemotingException ("Invalid time value");
649 int i
= s
.IndexOfAny (new char[] { 'D','H','M','S' }
);
655 unit
= s
.Substring (i
);
656 s
= s
.Substring (0,i
);
661 val
= double.Parse (s
);
664 throw new RemotingException ("Invalid time value: " + s
);
667 if (unit
== "D") return TimeSpan
.FromDays (val
);
668 if (unit
== "H") return TimeSpan
.FromHours (val
);
669 if (unit
== "M") return TimeSpan
.FromMinutes (val
);
670 if (unit
== "S") return TimeSpan
.FromSeconds (val
);
671 if (unit
== "MS") return TimeSpan
.FromMilliseconds (val
);
672 throw new RemotingException ("Invalid time unit: " + unit
);
675 void ReadChannel (MiniParser
.IAttrList attrs
, bool isTemplate
)
677 ChannelData channel
= new ChannelData ();
679 for (int i
=0; i
< attrs
.Names
.Length
; ++i
)
681 string at
= attrs
.Names
[i
];
682 string val
= attrs
.Values
[i
];
684 if (at
== "ref" && !isTemplate
)
686 else if (at
== "delayLoadAsClientChannel")
687 channel
.DelayLoadAsClientChannel
= val
;
688 else if (at
== "id" && isTemplate
)
690 else if (at
== "type")
693 channel
.CustomProperties
.Add (at
, val
);
698 if (channel
.Id
== null) throw new RemotingException ("id attribute is required");
699 if (channel
.Type
== null) throw new RemotingException ("id attribute is required");
700 RemotingConfiguration
.RegisterChannelTemplate (channel
);
703 channelInstances
.Add (channel
);
705 currentChannel
= channel
;
708 ProviderData
ReadProvider (string name
, MiniParser
.IAttrList attrs
, bool isTemplate
)
710 ProviderData prov
= (name
== "provider") ? new ProviderData () : new FormatterData ();
711 SinkProviderData data
= new SinkProviderData ("root");
712 prov
.CustomData
= data
.Children
;
714 currentProviderData
= new Stack ();
715 currentProviderData
.Push (data
);
717 for (int i
=0; i
< attrs
.Names
.Length
; ++i
)
719 string at
= attrs
.Names
[i
];
720 string val
= attrs
.Values
[i
];
722 if (at
== "id" && isTemplate
)
724 else if (at
== "type")
726 else if (at
== "ref" && !isTemplate
)
729 prov
.CustomProperties
.Add (at
, val
);
732 if (prov
.Id
== null && isTemplate
) throw new RemotingException ("id attribute is required");
736 void ReadClientActivated (MiniParser
.IAttrList attrs
)
738 string type
= GetNotNull (attrs
, "type");
739 string assm
= ExtractAssembly (ref type
);
741 if (currentClientUrl
== null || currentClientUrl
== "")
742 throw new RemotingException ("url attribute is required in client element when it contains activated entries");
744 typeEntries
.Add (new ActivatedClientTypeEntry (type
, assm
, currentClientUrl
));
747 void ReadServiceActivated (MiniParser
.IAttrList attrs
)
749 string type
= GetNotNull (attrs
, "type");
750 string assm
= ExtractAssembly (ref type
);
752 typeEntries
.Add (new ActivatedServiceTypeEntry (type
, assm
));
755 void ReadClientWellKnown (MiniParser
.IAttrList attrs
)
757 string url
= GetNotNull (attrs
, "url");
758 string type
= GetNotNull (attrs
, "type");
759 string assm
= ExtractAssembly (ref type
);
761 typeEntries
.Add (new WellKnownClientTypeEntry (type
, assm
, url
));
764 void ReadServiceWellKnown (MiniParser
.IAttrList attrs
)
766 string objectUri
= GetNotNull (attrs
, "objectUri");
767 string smode
= GetNotNull (attrs
, "mode");
768 string type
= GetNotNull (attrs
, "type");
769 string assm
= ExtractAssembly (ref type
);
771 WellKnownObjectMode mode
;
772 if (smode
== "SingleCall") mode
= WellKnownObjectMode
.SingleCall
;
773 else if (smode
== "Singleton") mode
= WellKnownObjectMode
.Singleton
;
774 else throw new RemotingException ("wellknown object mode '" + smode
+ "' is invalid");
776 typeEntries
.Add (new WellKnownServiceTypeEntry (type
, assm
, objectUri
, mode
));
779 void ReadInteropXml (MiniParser
.IAttrList attrs
, bool isElement
)
781 Type t
= Type
.GetType (GetNotNull (attrs
, "clr"));
782 string[] xmlName
= GetNotNull (attrs
, "xml").Split (',');
783 string localName
= xmlName
[0].Trim ();
784 string ns
= xmlName
.Length
> 0 ? xmlName
[1].Trim() : null;
786 if (isElement
) SoapServices
.RegisterInteropXmlElement (localName
, ns
, t
);
787 else SoapServices
.RegisterInteropXmlType (localName
, ns
, t
);
790 void ReadPreload (MiniParser
.IAttrList attrs
)
792 string type
= attrs
.GetValue ("type");
793 string assm
= attrs
.GetValue ("assembly");
795 if (type
!= null && assm
!= null)
796 throw new RemotingException ("Type and assembly attributes cannot be specified together");
799 SoapServices
.PreLoad (Type
.GetType (type
));
800 else if (assm
!= null)
801 SoapServices
.PreLoad (Assembly
.Load (assm
));
803 throw new RemotingException ("Either type or assembly attributes must be specified");
806 string GetNotNull (MiniParser
.IAttrList attrs
, string name
)
808 string value = attrs
.GetValue (name
);
809 if (value == null || value == "")
810 throw new RemotingException (name
+ " attribute is required");
814 string ExtractAssembly (ref string type
)
816 int i
= type
.IndexOf (',');
817 if (i
== -1) return "";
819 string asm
= type
.Substring (i
+1).Trim();
820 type
= type
.Substring (0, i
).Trim();
824 public void OnChars (string ch
) {}
826 public void OnEndParsing (MiniParser parser
)
828 RemotingConfiguration
.RegisterChannels (channelInstances
, onlyDelayedChannels
);
829 if (appName
!= null) RemotingConfiguration
.ApplicationName
= appName
;
831 if (!onlyDelayedChannels
)
832 RemotingConfiguration
.RegisterTypes (typeEntries
);
837 /*******************************************************************
838 * Internal data structures used by ConfigHandler, to store *
839 * machine.config's remoting related data. *
840 * If having them implemented this way, makes configuration too *
841 * slow, we can use string arrays. *
842 *******************************************************************/
844 internal class ChannelData
{
846 internal string Type
;
848 internal string DelayLoadAsClientChannel
;
850 ArrayList _serverProviders
= new ArrayList ();
851 ArrayList _clientProviders
= new ArrayList ();
852 Hashtable _customProperties
= new Hashtable ();
854 internal ArrayList ServerProviders
{
856 if (_serverProviders
== null) _serverProviders
= new ArrayList ();
857 return _serverProviders
;
861 public ArrayList ClientProviders
{
863 if (_clientProviders
== null) _clientProviders
= new ArrayList ();
864 return _clientProviders
;
868 public Hashtable CustomProperties
{
870 if (_customProperties
== null) _customProperties
= new Hashtable ();
871 return _customProperties
;
875 public void CopyFrom (ChannelData other
)
877 if (Ref
== null) Ref
= other
.Ref
;
878 if (Id
== null) Id
= other
.Id
;
879 if (Type
== null) Type
= other
.Type
;
880 if (DelayLoadAsClientChannel
== null) DelayLoadAsClientChannel
= other
.DelayLoadAsClientChannel
;
882 if (other
._customProperties
!= null)
884 foreach (DictionaryEntry entry
in other
._customProperties
)
885 if (!CustomProperties
.ContainsKey (entry
.Key
))
886 CustomProperties
[entry
.Key
] = entry
.Value
;
889 if (_serverProviders
== null && other
._serverProviders
!= null)
891 foreach (ProviderData prov
in other
._serverProviders
)
893 ProviderData np
= new ProviderData();
895 ServerProviders
.Add (np
);
899 if (_clientProviders
== null && other
._clientProviders
!= null)
901 foreach (ProviderData prov
in other
._clientProviders
)
903 ProviderData np
= new ProviderData();
905 ClientProviders
.Add (np
);
911 internal class ProviderData
{
913 internal string Type
;
916 internal Hashtable CustomProperties
= new Hashtable ();
917 internal IList CustomData
;
919 public void CopyFrom (ProviderData other
)
921 if (Ref
== null) Ref
= other
.Ref
;
922 if (Id
== null) Id
= other
.Id
;
923 if (Type
== null) Type
= other
.Type
;
925 foreach (DictionaryEntry entry
in other
.CustomProperties
)
926 if (!CustomProperties
.ContainsKey (entry
.Key
))
927 CustomProperties
[entry
.Key
] = entry
.Value
;
929 if (other
.CustomData
!= null)
931 if (CustomData
== null) CustomData
= new ArrayList ();
932 foreach (SinkProviderData data
in other
.CustomData
)
933 CustomData
.Add (data
);
938 internal class FormatterData
: ProviderData
{