カスタムWCFのプロファイル
4914 ワード
WCFのベアラは、符号化により実現するもよいし、配置により実現するもよい.また、構成を使用すると、今後のメンテナンスと拡張に役立ちます.WCFの構成情報を個別のファイルに置く必要がある場合、appのみを置くのではなく、独自のサービス構成を採用する必要がある場合がよくあります.config/web.config中..NETは、ConfigSourceを介したメカニズムを提供しています.例えばasp.NetのサイトでのデフォルトWeb.Configファイルで使用:
次に新しいcustomAppSettingsを作成します.Configファイル:
//////override ApplyConfiguration to load config from custom file/// protected override void ApplyConfiguration() {//get custom config file name by our rule: config file name = ServiceType.Name var myConfigFileName = this.Description.ServiceType.FullName;//get config file path string dir = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase; string myConfigFilePath = System.IO.Path.Combine(dir, myConfigFileName + ".config"); if (!System.IO.File.Exists(myConfigFilePath)) { base.ApplyConfiguration(); return; } var configFileMap = new System.Configuration.ExeConfigurationFileMap(); configFileMap.ExeConfigFilename = myConfigFilePath; var config = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None); var serviceModel = System.ServiceModel.Configuration.ServiceModelSectionGroup.GetSectionGroup(config); if (serviceModel == null) { base.ApplyConfiguration(); return; } foreach (ServiceElement serviceElement in serviceModel.Services.Services) { if (serviceElement.Name == this.Description.ServiceType.FullName) { LoadConfigurationSection(serviceElement); return; } } throw new Exception("there is no service element match the description!"); } } }
protected virtual void ApplyConfiguration(string configurationName); protected abstract ServiceEndpoint CreateDescription();
ApplyConfigurationメソッドとServiceHostのApplyConfigurationメソッドの機能は似ていますが、CreateDescriptionと対話する必要がある点が異なります.実はApplyConfigurationはクライアントエージェントではなく、CreateDescriptionに注目すればいいのです.
ChannelFactoryのメソッドCreateDescription実装はデフォルトプロファイル(デフォルトAppDomainのプロファイル)から行われるので、このメソッドを書き換えることで外部ファイルからの構成のロードを実現できます.
///
///Loads the serviceEndpoint description from the specified configuration file
///
///
protected override ServiceEndpoint CreateDescription()
{
ServiceEndpoint serviceEndpoint = base.CreateDescription();
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = this.configurationPath;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
ServiceModelSectionGroup group = ServiceModelSectionGroup.GetSectionGroup(config);
ChannelEndpointElement selectedEndpoint = null;
foreach (ChannelEndpointElement endpoint in group.Client.Endpoints)
{
if (endpoint.Contract == serviceEndpoint.Contract.ConfigurationName)
{
selectedEndpoint = endpoint;
break;
}
}
if (selectedEndpoint != null)
{
if (serviceEndpoint.Binding == null)
{
serviceEndpoint.Binding = CreateBinding(selectedEndpoint.Binding, group);
}
if (serviceEndpoint.Address == null)
{
serviceEndpoint.Address = new EndpointAddress(selectedEndpoint.Address, GetIdentity(selectedEndpoint.Identity), selectedEndpoint.Headers.Headers);
}
if (serviceEndpoint.Behaviors.Count == 0 && selectedEndpoint.BehaviorConfiguration != null)
{
AddBehaviors(selectedEndpoint.BehaviorConfiguration, serviceEndpoint, group);
}
serviceEndpoint.Name = selectedEndpoint.Contract;
}
return serviceEndpoint;
}
具体的な実装は、例コードを参照することができ、この例WCF sdkの例ICalculator.コードダウンロードCustomChannel.zip
次に新しいcustomAppSettingsを作成します.Configファイル:
<?xml version="1.0" encoding="utf-8"?>
<appSettings>
<add key="IsDev" value="True"/>
</appSettings>
, Web.Config , My.Config , 。
WCF configSource , WCF ?
WCF ServiceHost ChannelFactory<T> 。 。
1、 : ServiceHost ServiceHostBase , , :
protected virtual void ApplyConfiguration();
<system.serviceModel> , WCF 。 , :
///
2、WCF ,WCF ,ClientBase<T> ChannelFactory<T>,ClientBase ChannelFactory<T> Channel
ChannelFactory<T> :
protected virtual void ApplyConfiguration(string configurationName); protected abstract ServiceEndpoint CreateDescription();
ApplyConfigurationメソッドとServiceHostのApplyConfigurationメソッドの機能は似ていますが、CreateDescriptionと対話する必要がある点が異なります.実はApplyConfigurationはクライアントエージェントではなく、CreateDescriptionに注目すればいいのです.
ChannelFactory
///
///Loads the serviceEndpoint description from the specified configuration file
///
///
protected override ServiceEndpoint CreateDescription()
{
ServiceEndpoint serviceEndpoint = base.CreateDescription();
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = this.configurationPath;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
ServiceModelSectionGroup group = ServiceModelSectionGroup.GetSectionGroup(config);
ChannelEndpointElement selectedEndpoint = null;
foreach (ChannelEndpointElement endpoint in group.Client.Endpoints)
{
if (endpoint.Contract == serviceEndpoint.Contract.ConfigurationName)
{
selectedEndpoint = endpoint;
break;
}
}
if (selectedEndpoint != null)
{
if (serviceEndpoint.Binding == null)
{
serviceEndpoint.Binding = CreateBinding(selectedEndpoint.Binding, group);
}
if (serviceEndpoint.Address == null)
{
serviceEndpoint.Address = new EndpointAddress(selectedEndpoint.Address, GetIdentity(selectedEndpoint.Identity), selectedEndpoint.Headers.Headers);
}
if (serviceEndpoint.Behaviors.Count == 0 && selectedEndpoint.BehaviorConfiguration != null)
{
AddBehaviors(selectedEndpoint.BehaviorConfiguration, serviceEndpoint, group);
}
serviceEndpoint.Name = selectedEndpoint.Contract;
}
return serviceEndpoint;
}
具体的な実装は、例コードを参照することができ、この例WCF sdkの例ICalculator.コードダウンロードCustomChannel.zip