Adding a WCF service to an existing application?

I have an existing application that now requires interaction with a mobile device. The mobile device has a Wi-Fi connection and will connect to the PC on which the main application is located on the local network. A mobile device just needs to add / edit / find / delete objects supported by the main application. The main application is already encapsulating its functionality in some simple repository classes.

I believe the approach will be to add a WCF service to the main application, which provides a set of methods that a mobile device can call. However, I looked at WCF today and tried to set up an example application, but when it called WCF methods, it cannot access any data, so I feel that the WCF service is running in its own application domain and, as such, does not have access to the same static classes in the main application.

If I set up a WCF service project in VS 2008/2010, how can I run it in the same application domain as the main WinForms application, so that a remote application on the local network can contact it to receive data from the application.

Below is my WinForm sample

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" }); } } } 

What I need from the WCF service is access to TestDataProject.DataStore.GetInstance ();

Edit

I have achieved this

 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<ServiceMetadataBehavior>(); // 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 <ENTER> 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 } } 

With app.config containing

 <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="WindowsFormsApplication1.SimpleService"> </service> </services> <behaviors> <serviceBehaviors> <behavior name="SimpleServiceBehavior"> <serviceMetadata httpGetEnabled="True" policyVersion="Policy15" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration> 

Then I could use the WCF test client on the url http: // localhost: 8001 / MetadataSample

The main problem I was suffering with was that my service started automatically, it can be disabled in VS2010 using the project settings. Another problem was that UAC, since Visual Studio was not an administrator, the debugger could not host the service, this was fixed by adding the WindowsFormApplication1.MANIFEST file containing

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">" <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">" <security> <requestedPrivileges> <requestedExecutionLevel level="requireAdministrator"/> </requestedPrivileges> </security> </trustInfo> </assembly> 
+7
source share
2 answers

You created a WCF web service project that will work inside a web service process (usually IIS), and not inside your Windows forms process, and therefore it will not have any access to any data in static classes and properties in the Windows process Forms

It seems like your easiest option is to host the WCF service inside your windows forms application. I don’t want to dwell on how to do this, since there are several resources on the Internet (I also can hardly claim to be an expert!), But you can try the following article as a starting point:

+4
source

WCF services are deployed in the same assembly as the rest of the application, and must have access to any classes in it. You may have used a different namespace. If so, use the full name or using statement.

+2
source

All Articles