WCF客户端配置文件分离(自定义WCF客户端配置文件)
做了许许多多的WCF的开发,当自己的项目中引用越来越多的服务之后发现程序的配置文件越来越庞大,维护起这个配置文件来也就比较困难了。其实我们完全可以把这些WCF的配置分离出来到单独的文件中。这样使得服务的配置和程序的配置都很容易维护。
实现这个功能其实很简单,只需要重载一下ChannelFactory<T>里的一些方法。
这个类就是负责加载配置信息的类。下面给出我的代码:
实现这个功能其实很简单,只需要重载一下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 }
posted on 2009-07-20 18:06 wenwuxianren 阅读(1031) 评论(3) 编辑 收藏 举报