ExcelからWCFを呼び出す

仕事で嵌ったのでメモ。

Excel -> CCW -> WCF -> ASP.NET Service

こんな呼び出し方をする必要があったのですが、WCFの初期化をapp.configにやらせていました。Excelには当然、app.configがないのでWCFの呼び出しで失敗していまいます。Excel.exe.configを用意するという力技もありますが、C:\Program Files\Microsoft Office\Office12とかにファイルを置くのは気持ち悪いし、他社アプリがExcel.exe.configを使っている可能性もあるし、VistaUACとの兼ね合いもあるし、考えるまでもなくC:\Program Filesの下に手を出すのは却下。

次に、独自の構成ファイルを読み込んでメモリ上でマージすることを考えたのですが、client要素とbindings要素を設定したつもりだけどエラー。system.serviceModel要素を追い回すのは筋が悪そうなので、これも諦めて更なる方法を模索。

色々探してみたところ、
Pablo M. Cibraro (aka Cibrax) - Loading the WCF configuration from different files on the client side
WCFクライアントで独自の構成ファイルを読み込むというドンピシャなページを発見。これを採用することにしました。

これで、Excel.exe.configを作らなくてもよくなったし、いちいち自動生成されたapp.configをクライアントアプリにコピーする必要もなくなりました。
上記ページのCustomClientChannelの使い方はこんな感じ。

using System;
using System.Reflection;
using Microsoft.ServiceModel.Samples;
using WCFClient.ServiceReference1;

namespace WCFClient
{
    public static class ServiceCaller
    {
        public static string HelloWorld ()
        {
            // 任意の名前のアプリケーション構成ファイルを読み込んでWCFを初期化する
            // 例えば、xxx.dll.configを読み込んでみる
            string path = Assembly.GetExecutingAssembly ().Location + ".config";
            CustomClientChannel<Service1SoapChannel> ch = 
                new CustomClientChannel<Service1SoapChannel> (path);
            Service1SoapClient client = 
                new Service1SoapClient (ch.Endpoint.Binding,ch.Endpoint.Address);
            using (client)
            {
                return client.HelloWorld ();
            }
        }
    }
}

ただ、標準でこういうクラスを用意してもらいたいですね。