+ {
+ // Put the channel in the correct place according to its priority.
+ // Since there are not many channels, a linear search is ok.
+
+ lock (registeredChannels.SyncRoot)
+ {
+ int pos = -1;
+ for (int n = 0; n < registeredChannels.Count; n++)
+ {
+ IChannel regc = (IChannel) registeredChannels[n];
+
+ if (regc.ChannelName == chnl.ChannelName && chnl.ChannelName != "")
+ throw new RemotingException ("Channel " + regc.ChannelName + " already registered");
+
+ if (regc.ChannelPriority < chnl.ChannelPriority && pos==-1)
+ pos = n;
+ }
+
+ if (pos != -1) registeredChannels.Insert (pos, chnl);
+ else registeredChannels.Add (chnl);
+
+ IChannelReceiver receiver = chnl as IChannelReceiver;
+ if (receiver != null) receiver.StartListening (null);
+ }
+ }
+
+ internal static void RegisterChannelConfig (ChannelData channel)
+ {
+ IServerChannelSinkProvider serverSinks = null;
+ IClientChannelSinkProvider clientSinks = null;
+
+ // Create server providers
+ for (int n=channel.ServerProviders.Count-1; n>=0; n--)
+ {
+ ProviderData prov = channel.ServerProviders[n] as ProviderData;
+ IServerChannelSinkProvider sinkp = (IServerChannelSinkProvider) CreateProvider (prov);
+ sinkp.Next = serverSinks;
+ serverSinks = sinkp;
+ }
+
+ // Create client providers
+ for (int n=channel.ClientProviders.Count-1; n>=0; n--)
+ {
+ ProviderData prov = channel.ClientProviders[n] as ProviderData;
+ IClientChannelSinkProvider sinkp = (IClientChannelSinkProvider) CreateProvider (prov);
+ sinkp.Next = clientSinks;
+ clientSinks = sinkp;
+ }
+
+ // Create the channel
+
+ Type type = Type.GetType (channel.Type);
+ if (type == null) throw new RemotingException ("Type '" + channel.Type + "' not found");
+
+ Object[] parms;
+ Type[] signature;
+ bool clienc = typeof (IChannelSender).IsAssignableFrom (type);
+ bool serverc = typeof (IChannelReceiver).IsAssignableFrom (type);
+
+ if (clienc && serverc) {
+ signature = new Type [] {typeof(IDictionary), typeof(IClientChannelSinkProvider), typeof(IServerChannelSinkProvider)};
+ parms = new Object[] {channel.CustomProperties, clientSinks, serverSinks};
+ }
+ else if (clienc) {
+ signature = new Type [] {typeof(IDictionary), typeof(IClientChannelSinkProvider)};
+ parms = new Object[] {channel.CustomProperties, clientSinks};
+ }
+ else if (serverc) {
+ signature = new Type [] {typeof(IDictionary), typeof(IServerChannelSinkProvider)};
+ parms = new Object[] {channel.CustomProperties, serverSinks};
+ }
+ else
+ throw new RemotingException (type + " is not a valid channel type");
+
+ ConstructorInfo ctor = type.GetConstructor (signature);
+ if (ctor == null)
+ throw new RemotingException (type + " does not have a valid constructor");
+
+ IChannel ch;
+ try
+ {
+ ch = (IChannel) ctor.Invoke (parms);
+ }
+ catch (TargetInvocationException ex)
+ {
+ throw ex.InnerException;
+ }
+
+ lock (registeredChannels.SyncRoot)
+ {
+ if (channel.DelayLoadAsClientChannel == "true" && !(ch is IChannelReceiver))
+ delayedClientChannels.Add (ch);
+ else
+ RegisterChannel (ch);
+ }
+ }
+
+ static object CreateProvider (ProviderData prov)
+ {
+ Type pvtype = Type.GetType (prov.Type);
+ if (pvtype == null) throw new RemotingException ("Type '" + prov.Type + "' not found");
+ Object[] pvparms = new Object[] {prov.CustomProperties, prov.CustomData};
+
+ try
+ {
+ return Activator.CreateInstance (pvtype, pvparms);
+ }
+ catch (Exception ex)
+ {
+ if (ex is TargetInvocationException) ex = ((TargetInvocationException)ex).InnerException;
+ throw new RemotingException ("An instance of provider '" + pvtype + "' could not be created: " + ex.Message);
+ }