locked
How do I get a reference to my service class? RRS feed

  • Question

  • Howdy

    This should be an extremely common requirement and yet I can't find a word on it anywhere.
    So you write your service class, and you create your host, telling it what service class to use...

    host = New ServiceHost(GetType(Listener), baseURI_)

    That's fine and dandy... now how do I get a reference to the Listener I provided to the service host?

    If my listener raises events, I have no way to catch them.  If my listener receives data, I have no way to access it by my hosting application.

    How do I get a reference to the service I pass to the ServiceHost constructor?

    Many Thanks.

     

    Tuesday, February 16, 2010 4:11 AM

Answers

  • There are basically two options for this issue:
    - Define the service as a singleton - decorate the service class (Listener) with [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)], then use the other overload of the ServiceHost constructor, which takes a System.Object (instead of System.Type), and pass your instance of the Listener class. That instance of the Listener class is the one which will receive the calls made to the service
    - Use an IInstanceProvider so that you control the creation of the Listener instances. Then, prior to returning the instances to WCF, you can hook events, hold onto the reference, etc. The code below shows an example of this option.

        public class Post_9d57445e_44e9_4711_9c29_6eb7eb17ae3d
        {
            [ServiceContract]
            public interface ITest
            {
                [OperationContract]
                string EchoString(string text);
                [OperationContract]
                int Add(int x, int y);
            }
            public class Service : ITest
            {
                public string EchoString(string text)
                {
                    return text;
                }
    
                public int Add(int x, int y)
                {
                    return x + y;
                }
            }
            static Binding GetBinding()
            {
                BasicHttpBinding result = new BasicHttpBinding();
                return result;
            }
    
            public class MyInstanceProvider : IInstanceProvider, IContractBehavior
            {
                #region IInstanceProvider Members
    
                public object GetInstance(InstanceContext instanceContext, Message message)
                {
                    Service service = new Service();
                    Console.WriteLine("Returning service instance: {0}", service);
                    //register events, etc
                    return service;
                }
    
                public object GetInstance(InstanceContext instanceContext)
                {
                    Service service = new Service();
                    Console.WriteLine("Returning service instance: {0}", service);
                    //register events, etc
                    return service;
                }
    
                public void ReleaseInstance(InstanceContext instanceContext, object instance)
                {
                }
    
                #endregion
    
                #region IContractBehavior Members
    
                public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
                {
                }
    
                public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
                {
                }
    
                public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
                {
                    dispatchRuntime.InstanceProvider = this;
                }
    
                public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
                {
                }
    
                #endregion
            }
    
            public static void Test()
            {
                string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
                ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
                ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");
                endpoint.Contract.Behaviors.Add(new MyInstanceProvider());
                host.Open();
                Console.WriteLine("Host opened");
    
                ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));
                ITest proxy = factory.CreateChannel();
    
                Console.WriteLine(proxy.EchoString("Hello"));
                Console.WriteLine(proxy.Add(3, 5));
    
                ((IClientChannel)proxy).Close();
                factory.Close();
    
                Console.Write("Press ENTER to close the host");
                Console.ReadLine();
                host.Close();
            }
        }
    
    Tuesday, February 16, 2010 5:04 AM