简体   繁体   中英

How to debug a WCF call when it's a singleton and being run in a test

I am self-hosting a duplex-contract, WCF service. In composing a test that exercises if my client is receiving messages from the service, I have found that I can't debug the service itself. Thus, I made a simple example that seems to help me repeat the issue. This is an example of the test I'm attempting:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        ServiceRunner.Run(null);
        var client = new ServiceReference1.Service1Client();
        var result = client.GetData(11);
        Assert.IsNotNull(result);
        ServiceRunner.Host.Close();
    }
}

ServiceRunner will host the WCF contract in a singleton. The client is from a service reference that points to the self-hosted service. When I call GetData(11) I get a response, it's just that my breakpoint in the service is never hit. Why is that?

Here's the implementation of the service for completeness:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;

namespace CanYouDebugThis
{

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);
    }

    [ServiceBehaviorAttribute(InstanceContextMode = InstanceContextMode.Single)]
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            Console.WriteLine($"Get data with {value}");
            return string.Format("You entered: {0}", value);
        }
    }

    public class ServiceRunner
    {
        public static ServiceHost Host;
        public static void Run(String[] args)
        {
            var serviceInstance = new Service1();
            Uri baseAddress = new Uri("http://localhost:8080/hello");

            Host = new ServiceHost(serviceInstance, baseAddress);
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();

            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            Host.Description.Behaviors.Add(smb);
            Host.Open();
        }
    }
}

There is something wrong with hosting the service. We should add service endpoint and MEX endpoint for exchanging metadata. Please refer to the below code segments.

public static ServiceHost Host;
        public static void Main(String[] args)
        {
            var serviceInstance = new Service1();
            Uri baseAddress = new Uri("http://localhost:8080/hello");
            BasicHttpBinding binding = new BasicHttpBinding();
            //Host = new ServiceHost(serviceInstance, baseAddress);
            Host = new ServiceHost(typeof(Service1), baseAddress);
            Host.AddServiceEndpoint(typeof(IService1), binding, "");

            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            Host.Description.Behaviors.Add(smb);

            Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
            Host.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
            Host.Open();
            Console.WriteLine("Service is ready...");
            //pause, accepting a word would teminate the service.
            Console.ReadLine();
            Host.Close();
            Console.WriteLine("Service is closed....");
        }

Please host the service in an individual Console project first. Then on the client-side, we generate the client proxy by adding the service reference. Please pay attention to the auto-generated service endpoint, which should be corresponding to the actual server endpoint.
Result.
在此处输入图片说明
Feel free to let me know if there is anything I can help with.
Updated.

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        ServiceRunner.Run(null);
        ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
        var result = client.GetData(34);
        Assert.IsNotNull(result);
    }
}
[ServiceContract]
public interface IService1
{
    [OperationContract]
    string GetData(int value);
}

[ServiceBehaviorAttribute(InstanceContextMode = InstanceContextMode.Single)]
public class Service1 : IService1
{
    public string GetData(int value)
    {
        Console.WriteLine($"Get data with {value}");
        return string.Format("You entered: {0}", value);
    }
}

public class ServiceRunner
{
    public static ServiceHost Host;
    public static void Run(String[] args)
    {
        var serviceInstance = new Service1();
        Uri baseAddress = new Uri("http://localhost:8080/hello");

        Host = new ServiceHost(serviceInstance, baseAddress);
        ServiceMetadataBehavior smb = new ServiceMetadataBehavior();

        smb.HttpGetEnabled = true;
        smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
        Host.Description.Behaviors.Add(smb);
        Host.Open();
    }
}

Result.
在此处输入图片说明
At last, please pay attention to the automatically generated client endpoint address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM