WCF のデフォルトエンドポイント登録機能

.NET Framework 4.0 で WCF に追加される機能の中で、気になっているものの1つに、「デフォルトエンドポイントの登録」がある。サービスが実装するコントラクトと、ベースアドレスを元に、自動でエンドポイントを登録してくれるというシロモノ。

Visual Studio 2010(ベータ版) をようやくインストールしたので、さっそく試してみた。

using System;
using System.ServiceModel;

namespace WcfSample
{
    [ServiceContract]
    public interface IFooService
    {
        [OperationContract]
        string GetFoo();
    }

    [ServiceContract]
    public interface IBarService
    {
        [OperationContract]
        string GetBar();
    }

    public class SampleService : IFooService, IBarService
    {
        public string GetFoo()
        {
            return "Foo";
        }

        public string GetBar()
        {
            return "Bar";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string pipeAddress = "net.pipe://localhost/Sample";
            string tcpAddress = "net.tcp://localhost:8081/Sample";

            // 名前付きパイプと TCP のベースアドレスを指定
            ServiceHost host = new ServiceHost(
                typeof(SampleService),
                new Uri(pipeAddress),
                new Uri(tcpAddress));
            host.Open();

            // 登録されたデフォルトエンドポイントを表示
            foreach (var endpoint in host.Description.Endpoints)
            {
                Console.WriteLine("Address  : {0}", endpoint.Address);
                Console.WriteLine("Binding  : {0}", endpoint.Binding.Name);
                Console.WriteLine("Contract : {0}", endpoint.Contract.Name);
                Console.WriteLine();
            }

            // 名前付きパイプでアクセス
            IFooService foo = ChannelFactory<IFooService>.CreateChannel(
                new NetNamedPipeBinding(),
                new EndpointAddress(pipeAddress));
            Console.WriteLine(foo.GetFoo());
            
            // TCP でアクセス
            IBarService bar = ChannelFactory<IBarService>.CreateChannel(
                new NetTcpBinding(),
                new EndpointAddress(tcpAddress));
            Console.WriteLine(bar.GetBar());

            ((IClientChannel)foo).Close();
            ((IClientChannel)bar).Close();
            host.Close();

            Console.ReadLine();
        }
    }
}

f:id:griefworker:20100107105743p:image

名前付きパイプと TCP 両方のバインディングのエンドポイントが公開されている。また、サービスが実装しているコントラクトはすべて公開されている。

構成ファイルを書かなくていいし、AddServiceEndpoint メソッドを何度も呼び出す必要もない。コードがスッキリしていいね。今まで、ServiceHost を拡張して、同じような機能を自前で用意していたけど、もうお払い箱だな。