title: Adding WCF service to existing application?
body: <p>I have an existing application which now has the requirement to be interacted with from a mobile device. The mobile device has a wifi connection, and would be connecting to the PC hosting the main application on a LAN. The mobile device simply needs to add/edit/find/delete objects the main application is maintaining. The main application already encapsulates his functionality in some simple repository classes.</p>
  
  <p>I believe the approach would be to add a WCF service to the main application which exposes a set of methods the mobile device can call against. However I have looked up WCF today and tried to setup an example application, but when called the WCF methods it is unable to access any data, as such I feel the WCF service is running in its own application domain and as such has no access to the same static classes in the main application.</p>
  
  <p>If I setup a WCF service project in VS 2008/2010, how can I run it under the same application domain as the main WinForms application, so that a remote application on the LAN can communicate with it to get data from the application.</p>
  
  <p>Below is my sample WinForm</p>
  
  <pre><code>using System;
  using System.ServiceModel;
  using System.Windows.Forms;
  using DataProject;
  
  namespace WindowsFormsApplication1
  {
      public partial class Form1 : Form
      {
          public TestDataProject.DataStore Datastore = TestDataProject.DataStore.GetInstance();
  
          public Form1()
          {
              InitializeComponent();
              Datastore.Add(new MyObj { ID = 1, Data = "hello" });
              Datastore.Add(new MyObj { ID = 2, Data = "world" });
              Datastore.Add(new MyObj { ID = 3, Data = "item3" });
              Datastore.Add(new MyObj { ID = 4, Data = "item4" });
              Datastore.Add(new MyObj { ID = 5, Data = "fiver" });
          }
      }
  }
  </code></pre>
  
  <p>What I need from a WCF service, is access to TestDataProject.DataStore.GetInstance();</p>
  
  <p><strong>Edit</strong></p>
  
  <p>I achieved this by</p>
  
  <pre><code>using System;
  using System.ServiceModel;
  using System.ServiceModel.Description;
  using System.Windows.Forms;
  using DataProject;
  using TestDataProject;
  
  namespace WindowsFormsApplication1
  {
      public partial class Form1 : Form
      {
          public TestDataProject.DataStore Datastore = TestDataProject.DataStore.GetInstance();
  
          public Form1()
          {
              InitializeComponent();
              Datastore.Add(new MyObj { ID = 1, Data = "hello" });
              Datastore.Add(new MyObj { ID = 2, Data = "world" });
              Datastore.Add(new MyObj { ID = 3, Data = "item3" });
              Datastore.Add(new MyObj { ID = 4, Data = "item4" });
              Datastore.Add(new MyObj { ID = 5, Data = "fiver" });
  
              ServiceHost host = new ServiceHost(typeof(SimpleService),
                  new Uri("http://localhost:8001/MetadataSample"));
              try
              {
                  // Check to see if the service host already has a ServiceMetadataBehavior
                  ServiceMetadataBehavior smb = host.Description.Behaviors.Find&lt;ServiceMetadataBehavior&gt;();
                  // If not, add one
                  if (smb == null)
                      smb = new ServiceMetadataBehavior();
                  smb.HttpGetEnabled = true;
                  smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                  host.Description.Behaviors.Add(smb);
                  // Add MEX endpoint
                  host.AddServiceEndpoint(
                    ServiceMetadataBehavior.MexContractName,
                    MetadataExchangeBindings.CreateMexHttpBinding(),
                    "mex"
                  );
                  // Add application endpoint
                  host.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
  
                  // Open the service host to accept incoming calls
                  host.Open();
  
                  // The service can now be accessed.
                  Console.WriteLine("The service is ready.");
                  Console.WriteLine("Press &lt;ENTER&gt; to terminate service.");
                  Console.WriteLine();
                  Console.ReadLine();
  
                  // Close the ServiceHostBase to shutdown the service.
                  //host.Close();
              }
              catch (CommunicationException commProblem)
              {
                  Console.WriteLine("There was a communication problem. " + commProblem.Message);
                  Console.Read();
              }
  
          }
  
          public void Display(string msg)
          {
              MessageBox.Show(msg);
          }
      }
  
      [ServiceContract]
      public interface ISimpleService
      {
          [OperationContract]
          string Test();
  
          [OperationContract]
          string GetOBJDesc(int id);
  
          [OperationContract]
          MyObj GetObject(int id);
      }
  
      public class SimpleService : ISimpleService
      {
          #region Implementation of ISimpleService
  
          public string Test()
          {
              return "Hello world";
          }
  
          public string GetOBJDesc(int value)
          {
              MyObj obj = DataStore.GetInstance().Get(value);
              if (obj != null)
              {
                  return obj.Data;
              }
              return "";
          }
  
          public MyObj GetObject(int id)
          {
              return DataStore.GetInstance().Get(id);
          }
  
          #endregion
      }
  }
  </code></pre>
  
  <p>With app.config containing</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;configuration&gt;
    &lt;system.serviceModel&gt;
      &lt;services&gt;
        &lt;service name="WindowsFormsApplication1.SimpleService"&gt;
        &lt;/service&gt;
      &lt;/services&gt;
      &lt;behaviors&gt;
        &lt;serviceBehaviors&gt;
          &lt;behavior name="SimpleServiceBehavior"&gt;
            &lt;serviceMetadata httpGetEnabled="True" policyVersion="Policy15" /&gt;
          &lt;/behavior&gt;
        &lt;/serviceBehaviors&gt;
      &lt;/behaviors&gt;
    &lt;/system.serviceModel&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>I could then use WCF Test Client on the url <a href="http://localhost:8001/MetadataSample" rel="noreferrer">http://localhost:8001/MetadataSample</a></p>
  
  <p>The main issue I suffered from was my Service starting automatically, this can be disabled in VS2010 by a project setting. And the other issue was UAC, given Visual studio was not set to be a administrator the debugger failed to host a service, this was fixed by adding a WindowsFormApplication1.MANIFEST file containing</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
  &lt;assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"&gt;”
    &lt;trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"&gt;”
      &lt;security&gt;
        &lt;requestedPrivileges&gt;
          &lt;requestedExecutionLevel level="requireAdministrator"/&gt;
        &lt;/requestedPrivileges&gt;
      &lt;/security&gt;
    &lt;/trustInfo&gt;
  &lt;/assembly&gt;
  </code></pre>