实现这个功能其实很简单,只需要重载一下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
}