WCF入門-11 App.config以外のファイルからサービス構成を取得する

Sample SourceWCFServer.zip 直


クライアント側は、app.configの場合は、clientbaseを使いますが、別のファイル(例えば、other.config)から設定を読み込む場合は使えません。
ConfigurationManager.OpenMappedExeConfigurationを使ってConfigファイルを読み込んで、ConfigurationChannelFactoryを使ってchannelを作成します。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.Configuration;

namespace WCFInterfaces
{
public class CustomConfigClientBase
{
private ConfigurationChannelFactory _factory = null;
private Lazy _channel = null;

public string CustomConfigFileName { get; set;}
public string CustomEndpointName { get; set;}

private Type CreateChannel()
{
return CreateClientChannel(ref _factory, this.CustomConfigFileName, this.CustomEndpointName);
}

private T CreateClientChannel(ref ConfigurationChannelFactory configChannelFactory,
string configFilePath, string endPointName)
{
var fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configFilePath;
var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
configChannelFactory = new ConfigurationChannelFactory(endPointName, config, null);
return configChannelFactory.CreateChannel();
}

public CustomConfigClientBase()
{
_channel = new Lazy(CreateChannel, true);
}

public Type Channel
{
get{
return _channel.Value;
}
}

public void Close()
{
_factory.Close();
}
}
}

サーバー側は、app.configの場合は、servicehostを使いますが、別のファイルから読み込む場合は、ApplyConfigurationをオーバーライドする手法が使えます。
ApplyConfigurationがコンストラクタで呼び出されてしまうため、別ファイルのファイルパスはクラスのスタティック変数などで渡す必要があります。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.Configuration;

namespace WCFInterfaces
{
public class CustomConfigServiceHost : ServiceHost
{

public static string CustomConfigFileName {get; set;}

public CustomConfigServiceHost(Type serviceType) : base(serviceType)
{
}

protected override void ApplyConfiguration()
{
var filemap = new ExeConfigurationFileMap();
filemap.ExeConfigFilename = CustomConfigServiceHost.CustomConfigFileName;

var config = ConfigurationManager.OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None);
var serviceModel = ServiceModelSectionGroup.GetSectionGroup(config);

bool loaded = false;
foreach (ServiceElement se in serviceModel.Services.Services) {
if (!loaded)
if (se.Name == this.Description.ConfigurationName) {
base.LoadConfigurationSection(se);
loaded = true;
}
}
if (!loaded) {
throw new ArgumentException("Service Element not found in " + CustomConfigServiceHost.CustomConfigFileName);
}

base.ApplyConfiguration();

}

}
}

参照設定に、System.ServiceModelとSystem.Configurationが必要です。