实现这个功能其实很简单,只需要重载一下ChannelFactory<T>里的一些方法。
这个类就是负责加载配置信息的类。下面给出我的代码:
Code
希望会对其他人有些帮助
1/**//// <summary>
2 /// 自定义的客户端信道(允许从自定义的配置文件中加载)
3 /// </summary>
4 /// <typeparam name="T"></typeparam>
5 public class CustomClientChannel<T> : ChannelFactory<T>
6 {
7 string configurationPath;
8 string endpointConfigurationName;
9
10 /**//// <summary>
11 /// 构造函数
12 /// </summary>
13 /// <param name="configurationPath"></param>
14 public CustomClientChannel(string configurationPath)
15 : base(typeof(T))
16 {
17 this.configurationPath = configurationPath;
18 base.InitializeEndpoint((string)null, null);
19 }
20
21 /**//// <summary>
22 /// 构造函数
23 /// </summary>
24 /// <param name="binding"></param>
25 /// <param name="configurationPath"></param>
26 public CustomClientChannel(Binding binding, string configurationPath)
27 : this(binding, (EndpointAddress)null, configurationPath)
28 {
29 }
30
31 /**//// <summary>
32 /// 构造函数
33 /// </summary>
34 /// <param name="serviceEndpoint"></param>
35 /// <param name="configurationPath"></param>
36 public CustomClientChannel(ServiceEndpoint serviceEndpoint, string configurationPath)
37 : base(typeof(T))
38 {
39 this.configurationPath = configurationPath;
40 base.InitializeEndpoint(serviceEndpoint);
41 }
42
43 /**//// <summary>
44 /// 构造函数
45 /// </summary>
46 /// <param name="endpointConfigurationName"></param>
47 /// <param name="configurationPath"></param>
48 public CustomClientChannel(string endpointConfigurationName, string configurationPath)
49 : this(endpointConfigurationName, null, configurationPath)
50 {
51 }
52
53 /**//// <summary>
54 /// 构造函数
55 /// </summary>
56 /// <param name="binding"></param>
57 /// <param name="endpointAddress"></param>
58 /// <param name="configurationPath"></param>
59 public CustomClientChannel(Binding binding, EndpointAddress endpointAddress, string configurationPath)
60 : base(typeof(T))
61 {
62 this.configurationPath = configurationPath;
63 base.InitializeEndpoint(binding, endpointAddress);
64 }
65
66 /**//// <summary>
67 /// 构造函数
68 /// </summary>
69 /// <param name="binding"></param>
70 /// <param name="remoteAddress"></param>
71 /// <param name="configurationPath"></param>
72 public CustomClientChannel(Binding binding, string remoteAddress, string configurationPath)
73 : this(binding, new EndpointAddress(remoteAddress), configurationPath)
74 {
75 }
76
77 /**//// <summary>
78 /// 构造函数
79 /// </summary>
80 /// <param name="endpointConfigurationName"></param>
81 /// <param name="endpointAddress"></param>
82 /// <param name="configurationPath"></param>
83 public CustomClientChannel(string endpointConfigurationName, EndpointAddress endpointAddress, string configurationPath)
84 : base(typeof(T))
85 {
86 this.configurationPath = configurationPath;
87 this.endpointConfigurationName = endpointConfigurationName;
88 base.InitializeEndpoint(endpointConfigurationName, endpointAddress);
89 }
90
91 /**//// <summary>
92 /// 从自定义配置文件中加载终结点描述
93 /// </summary>
94 /// <returns></returns>
95 protected override ServiceEndpoint CreateDescription()
96 {
97 ServiceEndpoint serviceEndpoint = base.CreateDescription();
98
99 if (endpointConfigurationName != null)
100 serviceEndpoint.Name = endpointConfigurationName;
101
102 ExeConfigurationFileMap map = new ExeConfigurationFileMap();
103 map.ExeConfigFilename = this.configurationPath;
104
105 Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
106 ServiceModelSectionGroup group = ServiceModelSectionGroup.GetSectionGroup(config);
107
108 ChannelEndpointElement selectedEndpoint = null;
109
110 foreach (ChannelEndpointElement endpoint in group.Client.Endpoints)
111 {
112 if (endpoint.Contract == serviceEndpoint.Contract.ConfigurationName &&
113 (this.endpointConfigurationName == null || this.endpointConfigurationName == endpoint.Name))
114 {
115 selectedEndpoint = endpoint;
116 break;
117 }
118 }
119
120 if (selectedEndpoint != null)
121 {
122 if (serviceEndpoint.Binding == null)
123 {
124 serviceEndpoint.Binding = CreateBinding(selectedEndpoint.Binding, group);
125 }
126
127 if (serviceEndpoint.Address == null)
128 {
129 serviceEndpoint.Address = new EndpointAddress(selectedEndpoint.Address, GetIdentity(selectedEndpoint.Identity), selectedEndpoint.Headers.Headers);
130 }
131
132 if (serviceEndpoint.Behaviors.Count == 0 && selectedEndpoint.BehaviorConfiguration != null)
133 {
134 AddBehaviors(selectedEndpoint.BehaviorConfiguration, serviceEndpoint, group);
135 }
136
137 serviceEndpoint.Name = selectedEndpoint.Contract;
138 }
139
140 return serviceEndpoint;
141
142 }
143
144 /**//// <summary>
145 /// 为所选择的终结点配置绑定
146 /// </summary>
147 /// <param name="bindingName"></param>
148 /// <param name="group"></param>
149 /// <returns></returns>
150 private Binding CreateBinding(string bindingName, ServiceModelSectionGroup group)
151 {
152 BindingCollectionElement bindingElementCollection = group.Bindings[bindingName];
153 if (bindingElementCollection.ConfiguredBindings.Count > 0)
154 {
155 IBindingConfigurationElement be = bindingElementCollection.ConfiguredBindings[0];
156
157 Binding binding = GetBinding(be);
158 if (be != null)
159 {
160 be.ApplyConfiguration(binding);
161 }
162
163 return binding;
164 }
165
166 return null;
167 }
168
169 /**//// <summary>
170 /// 一些创建匹配绑定的方法
171 /// </summary>
172 /// <param name="configurationElement"></param>
173 /// <returns></returns>
174 private Binding GetBinding(IBindingConfigurationElement configurationElement)
175 {
176 if (configurationElement is CustomBindingElement)
177 return new CustomBinding();
178 else if (configurationElement is BasicHttpBindingElement)
179 return new BasicHttpBinding();
180 else if (configurationElement is NetMsmqBindingElement)
181 return new NetMsmqBinding();
182 else if (configurationElement is NetNamedPipeBindingElement)
183 return new NetNamedPipeBinding();
184 else if (configurationElement is NetPeerTcpBindingElement)
185 return new NetPeerTcpBinding();
186 else if (configurationElement is NetTcpBindingElement)
187 return new NetTcpBinding();
188 else if (configurationElement is WSDualHttpBindingElement)
189 return new WSDualHttpBinding();
190 else if (configurationElement is WSHttpBindingElement)
191 return new WSHttpBinding();
192 else if (configurationElement is WSFederationHttpBindingElement)
193 return new WSFederationHttpBinding();
194
195 return null;
196 }
197
198 /**//// <summary>
199 /// 添加configured behavior 到所选择的终结点
200 /// </summary>
201 /// <param name="behaviorConfiguration"></param>
202 /// <param name="serviceEndpoint"></param>
203 /// <param name="group"></param>
204 private void AddBehaviors(string behaviorConfiguration, ServiceEndpoint serviceEndpoint, ServiceModelSectionGroup group)
205 {
206 //如果没有配置客户端行为则不执行
207 if (String.IsNullOrEmpty(behaviorConfiguration))
208 {
209 return;
210 }
211
212 EndpointBehaviorElement behaviorElement = group.Behaviors.EndpointBehaviors[behaviorConfiguration];
213 for (int i = 0; i < behaviorElement.Count; i++)
214 {
215 BehaviorExtensionElement behaviorExtension = behaviorElement[i];
216 object extension = behaviorExtension.GetType().InvokeMember("CreateBehavior",
217 BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
218 null, behaviorExtension, null);
219 if (extension != null)
220 {
221 serviceEndpoint.Behaviors.Add((IEndpointBehavior)extension);
222 }
223 }
224 }
225
226 /**//// <summary>
227 /// 从配置文件重获取终结点的identity
228 /// </summary>
229 /// <param name="element"></param>
230 /// <returns></returns>
231 private EndpointIdentity GetIdentity(IdentityElement element)
232 {
233 EndpointIdentity identity = null;
234 PropertyInformationCollection properties = element.ElementInformation.Properties;
235 if (properties["userPrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
236 {
237 return EndpointIdentity.CreateUpnIdentity(element.UserPrincipalName.Value);
238 }
239 if (properties["servicePrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
240 {
241 return EndpointIdentity.CreateSpnIdentity(element.ServicePrincipalName.Value);
242 }
243 if (properties["dns"].ValueOrigin != PropertyValueOrigin.Default)
244 {
245 return EndpointIdentity.CreateDnsIdentity(element.Dns.Value);
246 }
247 if (properties["rsa"].ValueOrigin != PropertyValueOrigin.Default)
248 {
249 return EndpointIdentity.CreateRsaIdentity(element.Rsa.Value);
250 }
251 if (properties["certificate"].ValueOrigin != PropertyValueOrigin.Default)
252 {
253 X509Certificate2Collection supportingCertificates = new X509Certificate2Collection();
254 supportingCertificates.Import(Convert.FromBase64String(element.Certificate.EncodedValue));
255 if (supportingCertificates.Count == 0)
256 {
257 throw new InvalidOperationException("UnableToLoadCertificateIdentity");
258 }
259 X509Certificate2 primaryCertificate = supportingCertificates[0];
260 supportingCertificates.RemoveAt(0);
261 return EndpointIdentity.CreateX509CertificateIdentity(primaryCertificate, supportingCertificates);
262 }
263
264 return identity;
265 }
266
267
268 protected override void ApplyConfiguration(string configurationName)
269 {
270 base.ApplyConfiguration(configurationName);
271 }
272
273 }
希望会对其他人有些帮助
1/**//// <summary>
2 /// 自定义的客户端信道(允许从自定义的配置文件中加载)
3 /// </summary>
4 /// <typeparam name="T"></typeparam>
5 public class CustomClientChannel<T> : ChannelFactory<T>
6 {
7 string configurationPath;
8 string endpointConfigurationName;
9
10 /**//// <summary>
11 /// 构造函数
12 /// </summary>
13 /// <param name="configurationPath"></param>
14 public CustomClientChannel(string configurationPath)
15 : base(typeof(T))
16 {
17 this.configurationPath = configurationPath;
18 base.InitializeEndpoint((string)null, null);
19 }
20
21 /**//// <summary>
22 /// 构造函数
23 /// </summary>
24 /// <param name="binding"></param>
25 /// <param name="configurationPath"></param>
26 public CustomClientChannel(Binding binding, string configurationPath)
27 : this(binding, (EndpointAddress)null, configurationPath)
28 {
29 }
30
31 /**//// <summary>
32 /// 构造函数
33 /// </summary>
34 /// <param name="serviceEndpoint"></param>
35 /// <param name="configurationPath"></param>
36 public CustomClientChannel(ServiceEndpoint serviceEndpoint, string configurationPath)
37 : base(typeof(T))
38 {
39 this.configurationPath = configurationPath;
40 base.InitializeEndpoint(serviceEndpoint);
41 }
42
43 /**//// <summary>
44 /// 构造函数
45 /// </summary>
46 /// <param name="endpointConfigurationName"></param>
47 /// <param name="configurationPath"></param>
48 public CustomClientChannel(string endpointConfigurationName, string configurationPath)
49 : this(endpointConfigurationName, null, configurationPath)
50 {
51 }
52
53 /**//// <summary>
54 /// 构造函数
55 /// </summary>
56 /// <param name="binding"></param>
57 /// <param name="endpointAddress"></param>
58 /// <param name="configurationPath"></param>
59 public CustomClientChannel(Binding binding, EndpointAddress endpointAddress, string configurationPath)
60 : base(typeof(T))
61 {
62 this.configurationPath = configurationPath;
63 base.InitializeEndpoint(binding, endpointAddress);
64 }
65
66 /**//// <summary>
67 /// 构造函数
68 /// </summary>
69 /// <param name="binding"></param>
70 /// <param name="remoteAddress"></param>
71 /// <param name="configurationPath"></param>
72 public CustomClientChannel(Binding binding, string remoteAddress, string configurationPath)
73 : this(binding, new EndpointAddress(remoteAddress), configurationPath)
74 {
75 }
76
77 /**//// <summary>
78 /// 构造函数
79 /// </summary>
80 /// <param name="endpointConfigurationName"></param>
81 /// <param name="endpointAddress"></param>
82 /// <param name="configurationPath"></param>
83 public CustomClientChannel(string endpointConfigurationName, EndpointAddress endpointAddress, string configurationPath)
84 : base(typeof(T))
85 {
86 this.configurationPath = configurationPath;
87 this.endpointConfigurationName = endpointConfigurationName;
88 base.InitializeEndpoint(endpointConfigurationName, endpointAddress);
89 }
90
91 /**//// <summary>
92 /// 从自定义配置文件中加载终结点描述
93 /// </summary>
94 /// <returns></returns>
95 protected override ServiceEndpoint CreateDescription()
96 {
97 ServiceEndpoint serviceEndpoint = base.CreateDescription();
98
99 if (endpointConfigurationName != null)
100 serviceEndpoint.Name = endpointConfigurationName;
101
102 ExeConfigurationFileMap map = new ExeConfigurationFileMap();
103 map.ExeConfigFilename = this.configurationPath;
104
105 Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
106 ServiceModelSectionGroup group = ServiceModelSectionGroup.GetSectionGroup(config);
107
108 ChannelEndpointElement selectedEndpoint = null;
109
110 foreach (ChannelEndpointElement endpoint in group.Client.Endpoints)
111 {
112 if (endpoint.Contract == serviceEndpoint.Contract.ConfigurationName &&
113 (this.endpointConfigurationName == null || this.endpointConfigurationName == endpoint.Name))
114 {
115 selectedEndpoint = endpoint;
116 break;
117 }
118 }
119
120 if (selectedEndpoint != null)
121 {
122 if (serviceEndpoint.Binding == null)
123 {
124 serviceEndpoint.Binding = CreateBinding(selectedEndpoint.Binding, group);
125 }
126
127 if (serviceEndpoint.Address == null)
128 {
129 serviceEndpoint.Address = new EndpointAddress(selectedEndpoint.Address, GetIdentity(selectedEndpoint.Identity), selectedEndpoint.Headers.Headers);
130 }
131
132 if (serviceEndpoint.Behaviors.Count == 0 && selectedEndpoint.BehaviorConfiguration != null)
133 {
134 AddBehaviors(selectedEndpoint.BehaviorConfiguration, serviceEndpoint, group);
135 }
136
137 serviceEndpoint.Name = selectedEndpoint.Contract;
138 }
139
140 return serviceEndpoint;
141
142 }
143
144 /**//// <summary>
145 /// 为所选择的终结点配置绑定
146 /// </summary>
147 /// <param name="bindingName"></param>
148 /// <param name="group"></param>
149 /// <returns></returns>
150 private Binding CreateBinding(string bindingName, ServiceModelSectionGroup group)
151 {
152 BindingCollectionElement bindingElementCollection = group.Bindings[bindingName];
153 if (bindingElementCollection.ConfiguredBindings.Count > 0)
154 {
155 IBindingConfigurationElement be = bindingElementCollection.ConfiguredBindings[0];
156
157 Binding binding = GetBinding(be);
158 if (be != null)
159 {
160 be.ApplyConfiguration(binding);
161 }
162
163 return binding;
164 }
165
166 return null;
167 }
168
169 /**//// <summary>
170 /// 一些创建匹配绑定的方法
171 /// </summary>
172 /// <param name="configurationElement"></param>
173 /// <returns></returns>
174 private Binding GetBinding(IBindingConfigurationElement configurationElement)
175 {
176 if (configurationElement is CustomBindingElement)
177 return new CustomBinding();
178 else if (configurationElement is BasicHttpBindingElement)
179 return new BasicHttpBinding();
180 else if (configurationElement is NetMsmqBindingElement)
181 return new NetMsmqBinding();
182 else if (configurationElement is NetNamedPipeBindingElement)
183 return new NetNamedPipeBinding();
184 else if (configurationElement is NetPeerTcpBindingElement)
185 return new NetPeerTcpBinding();
186 else if (configurationElement is NetTcpBindingElement)
187 return new NetTcpBinding();
188 else if (configurationElement is WSDualHttpBindingElement)
189 return new WSDualHttpBinding();
190 else if (configurationElement is WSHttpBindingElement)
191 return new WSHttpBinding();
192 else if (configurationElement is WSFederationHttpBindingElement)
193 return new WSFederationHttpBinding();
194
195 return null;
196 }
197
198 /**//// <summary>
199 /// 添加configured behavior 到所选择的终结点
200 /// </summary>
201 /// <param name="behaviorConfiguration"></param>
202 /// <param name="serviceEndpoint"></param>
203 /// <param name="group"></param>
204 private void AddBehaviors(string behaviorConfiguration, ServiceEndpoint serviceEndpoint, ServiceModelSectionGroup group)
205 {
206 //如果没有配置客户端行为则不执行
207 if (String.IsNullOrEmpty(behaviorConfiguration))
208 {
209 return;
210 }
211
212 EndpointBehaviorElement behaviorElement = group.Behaviors.EndpointBehaviors[behaviorConfiguration];
213 for (int i = 0; i < behaviorElement.Count; i++)
214 {
215 BehaviorExtensionElement behaviorExtension = behaviorElement[i];
216 object extension = behaviorExtension.GetType().InvokeMember("CreateBehavior",
217 BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
218 null, behaviorExtension, null);
219 if (extension != null)
220 {
221 serviceEndpoint.Behaviors.Add((IEndpointBehavior)extension);
222 }
223 }
224 }
225
226 /**//// <summary>
227 /// 从配置文件重获取终结点的identity
228 /// </summary>
229 /// <param name="element"></param>
230 /// <returns></returns>
231 private EndpointIdentity GetIdentity(IdentityElement element)
232 {
233 EndpointIdentity identity = null;
234 PropertyInformationCollection properties = element.ElementInformation.Properties;
235 if (properties["userPrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
236 {
237 return EndpointIdentity.CreateUpnIdentity(element.UserPrincipalName.Value);
238 }
239 if (properties["servicePrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
240 {
241 return EndpointIdentity.CreateSpnIdentity(element.ServicePrincipalName.Value);
242 }
243 if (properties["dns"].ValueOrigin != PropertyValueOrigin.Default)
244 {
245 return EndpointIdentity.CreateDnsIdentity(element.Dns.Value);
246 }
247 if (properties["rsa"].ValueOrigin != PropertyValueOrigin.Default)
248 {
249 return EndpointIdentity.CreateRsaIdentity(element.Rsa.Value);
250 }
251 if (properties["certificate"].ValueOrigin != PropertyValueOrigin.Default)
252 {
253 X509Certificate2Collection supportingCertificates = new X509Certificate2Collection();
254 supportingCertificates.Import(Convert.FromBase64String(element.Certificate.EncodedValue));
255 if (supportingCertificates.Count == 0)
256 {
257 throw new InvalidOperationException("UnableToLoadCertificateIdentity");
258 }
259 X509Certificate2 primaryCertificate = supportingCertificates[0];
260 supportingCertificates.RemoveAt(0);
261 return EndpointIdentity.CreateX509CertificateIdentity(primaryCertificate, supportingCertificates);
262 }
263
264 return identity;
265 }
266
267
268 protected override void ApplyConfiguration(string configurationName)
269 {
270 base.ApplyConfiguration(configurationName);
271 }
272
273 }