さて、Silverlight コンポーネントを含む ASP.NET アプリケーションを複数のステージング環境にデプロイする必要があります。アプリは、別のプロジェクトの一部である Wcf サービスに依存していますが、常にプロジェクトと同じサーバーでホストする必要があります (別のポートではありますが)。新しい環境にデプロイするたびに、ServiceReferences.ClientConfig ファイルでサービスのエンドポイントのアドレスを変更することを覚えておく必要はありません。プロジェクトに複数の ServiceReferences.ClientConfig(s) を指定する方法がないため (Web.Config(s) でできるように)、こちらのアドバイスに従いました。ServiceReferences.ClientConfig で各環境の参照を作成します。次に、目的のエンドポイントの名前をメイン プロジェクトの Web.config の設定として指定し、それを初期パラメーターとして Silverlight コンポーネントに渡します。ここで壁にぶち当たりました。slsvcutil を使用して、Web サービスの非同期クライアントを生成します。私の知る限り、目的のエンドポイント アドレスをサービス クライアントに渡す唯一の方法は、そのコンストラクターを使用することです。典型的なサービス呼び出しの例を次に示します。
yield return new WebServiceResult<ServiceClient, MethodCallCompletedEventArgs>
(
client => client.MethodNameAsync(param1, param2, ...),
result => { .... }
);
以下は、クラス WebServiceResult の簡略化された定義です。
public class WebServiceResult<T, K> : IResult
where T : new()
where K : EventArgs
{
private readonly Action<K> _callback;
private readonly Expression<Action<T>> _serviceCall;
private ActionExecutionContext _currentContext;
public WebServiceResult(Expression<Action<T>> serviceCall, Action<K> callback)
{
_serviceCall = serviceCall;
_callback = callback;
}
public void Execute(ActionExecutionContext context)
{
_currentContext = context;
var lambda = (LambdaExpression)_serviceCall;
var methodCall = (MethodCallExpression)lambda.Body;
var eventName = methodCall.Method.Name.Replace("Async", "Completed");
var eventInfo = typeof(T).GetEvent(eventName);
var service = new T();
eventInfo.AddEventHandler(service, new EventHandler<K>(OnEvent));
_serviceCall.Compile()(service);
}
public void OnEvent(object sender, K args)
{
if (_callback != null) _callback(args);
}
}
ジェネリック T はパラメーターなしのコンストラクターを持つものに制限されているため、目的の endpointAddress の名前をどのように指定すればよいですか?