読者です 読者をやめる 読者になる 読者になる

WCF サービスクラスの継承

既存の WCF サービスを継承した新しい WCF サービスを作成し、ServiceHost でホストしたらどんな動作をするか試してみました。

結果を忘れないようにメモしておきます。

using System;
using System.ServiceModel;

namespace InheritanceSample
{
    class Program
    {
        [ServiceContract]
        public interface IFooService
        {
            [OperationContract]
            string GetFoo();
        }

        public class FooService : IFooService
        {
            public string GetFoo() { return "Foo"; }
        }

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

        // FooService を継承し、IBarService を実装する
        public class BarService : FooService, IBarService
        {
            public string GetBar() { return "Bar"; }
        }

        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(BarService));

            // IBarService のエンドポイント登録
            string barAddress = "net.pipe://localhost/BarService";
            host.AddServiceEndpoint(typeof(IBarService),
                new NetNamedPipeBinding(),
                barAddress);

            // IFooService のエンドポイント登録。
            // 同じアドレスは指定できない。
            // IFooService のエンドポイントを登録しておかないと、
            // IFooService のチャネルでアクセスできない。
            // IBarService が IFooService を継承している場合は、
            // 登録しなくてもアクセスできる。
            string fooAddress = "net.pipe://localhost/FooService";
            host.AddServiceEndpoint(typeof(IFooService),
                new NetNamedPipeBinding(),
                fooAddress);

            host.Open();

            IFooService fooProxy = ChannelFactory<IFooService>.CreateChannel(
                new NetNamedPipeBinding(),
                new EndpointAddress(fooAddress));
            Console.WriteLine(fooProxy.GetFoo());
            ((IClientChannel)fooProxy).Close();

            IBarService barProxy = ChannelFactory<IBarService>.CreateChannel(
                new NetNamedPipeBinding(),
                new EndpointAddress(barAddress));
            Console.WriteLine(barProxy.GetBar());
            ((IClientChannel)barProxy).Close();

            Console.ReadLine();
            host.Close();
        }
    }
}

サンプルの実行結果が下図。

f:id:griefworker:20090825201414p:image
継承元のサービスクラスが実装するインタフェースを使ってサービスを呼び出すには、エンドポイントを登録すれば可能です。予想通りですけど。