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