これは私が思っていたよりも少し大変でした。WCF には非常に多くの拡張ポイントがあり、適切なものを選択するのは困難です。より良い方法があると思われる場合、またはこれに何か問題があると思われる場合は、回答またはコメントしてください。
IEndpointBehaviorとIDispatchMessageInspectorを実装するカスタム クラスを使用することにしました。BehaviorExtensionElementから派生したクラスがあり、構成で動作をエンドポイントに関連付けることができます。 このブログ投稿では、ホット ドゥ ドゥ について説明しています。
私DatabaseConnectionContext
のクラスは次のようになります。
/// <summary>
/// An endpoint behavior that associates a database connection string name with the endpoint and adds it to the
/// properties of incoming messages.
/// </summary>
public class DatabaseConnectionContext : IEndpointBehavior, IDispatchMessageInspector
{
/// <summary>
/// Initializes a new instance of the <see cref="DatabaseConnectionContext"/> class with the provided connection string name.
/// </summary>
/// <param name="connectionStringName">The name of the connection string to associate with the endpoint.</param>
public DatabaseConnectionContext(string connectionStringName)
{
this.ConnectionStringName = connectionStringName;
}
/// <summary>
/// Gets the name of the connection string to associate with the endpoint.
/// </summary>
public string ConnectionStringName { get; private set; }
/// <inheritdoc />
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
/// <inheritdoc />
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
}
/// <inheritdoc />
public void Validate(ServiceEndpoint endpoint)
{
}
/// <inheritdoc />
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
request.Properties["connectionStringName"] = this.ConnectionStringName;
return null;
}
/// <inheritdoc />
public void BeforeSendReply(ref Message reply, object correlationState)
{
}
}
私のサービスクラスには、次のメソッドがあります。
/// <summary>
/// Returns the connection string to use for this service call.
/// </summary>
/// <returns>A SQL Server database connection string.</returns>
private string GetConnectionString()
{
string connectionStringName = (string)OperationContext.Current.IncomingMessageProperties["connectionStringName"];
return ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
}
私BehaviorExtensionElement
のクラスは次のようになります。
/// <summary>
/// Associates a <see cref="DatabaseConnectionContext"/> with an endpoint in configuration.
/// </summary>
public class DatabaseConnectionContextBehaviorExtension : BehaviorExtensionElement
{
/// <summary>
/// The name of the <see cref="ConnectionStringName"/> property when it appears in a configuration file.
/// </summary>
private const string ConnectionStringNamePropertyName = "connectionStringName";
/// <summary>
/// Gets or sets the name of the configuration string to associate with the endpoint.
/// </summary>
[ConfigurationProperty(ConnectionStringNamePropertyName)]
public string ConnectionStringName
{
get
{
return (string)this[ConnectionStringNamePropertyName];
}
set
{
this[ConnectionStringNamePropertyName] = value;
}
}
/// <inheritdoc />
public override Type BehaviorType
{
get { return typeof(DatabaseConnectionContext); }
}
/// <inheritdoc />
protected override object CreateBehavior()
{
return new DatabaseConnectionContext(this.ConnectionStringName);
}
}
私のweb.configには次のようなものが含まれています:
<behaviors>
<endpointBehaviors>
<behavior name="DevRestEndpointConfiguration">
<webHttp helpEnabled="false" />
<connectionStringInterceptor connectionStringName="myDevConnectionStringName" />
</behavior>
<behavior name="ProductionRestEndpointConfiguration">
<webHttp helpEnabled="false" />
<connectionStringInterceptor connectionStringName="myProductionConnectionStringName" />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="connectionStringInterceptor" type="DatabaseConnectionContextBehaviorExtension, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
セクションの各<endpoint />
要素には、<services />
セクションbehaviorConfiguration
の適切な要素の名前が設定されてい<endpointBehaviors />
ます。