将WCF服务添加到现有应用程序?

Jon*_*lis 8 c# wcf windows-mobile winforms

我有一个现有的应用程序,现在需要与移动设备进行交互.移动设备具有wifi连接,并且将连接到在LAN上托管主应用程序的PC.移动设备只需添加/编辑/查找/删除主应用程序正在维护的对象.主应用程序已将其功能封装在一些简单的存储库类中.

我相信这种方法是向主应用程序添加一个WCF服务,该服务公开了移动设备可以调用的一组方法.但是我今天查找了WCF并试图设置一个示例应用程序,但是当调用WCF方法时它无法访问任何数据,因此我觉得WCF服务在其自己的应用程序域中运行,因此无法访问主应用程序中的相同静态类.

如果我在VS 2008/2010中设置WCF服务项目,我如何在与主WinForms应用程序相同的应用程序域下运行它,以便LAN上的远程应用程序可以与它通信以从应用程序获取数据.

下面是我的WinForm示例

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" });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要从WCF服务访问TestDataProject.DataStore.GetInstance();

编辑

我实现了这个目标

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
    }
}
Run Code Online (Sandbox Code Playgroud)

使用app.config

<?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>
Run Code Online (Sandbox Code Playgroud)

然后,我可以在URL http:// localhost:8001/MetadataSample上使用WCF测试客户端

我遇到的主要问题是我的服务自动启动,这可以通过项目设置在VS2010中禁用.另一个问题是UAC,因为Visual Studio未设置为管理员调试器无法托管服务,这是通过添加一个包含WindowsFormApplication1.MANIFEST文件修复的

<?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>
Run Code Online (Sandbox Code Playgroud)

Jus*_*tin 4

您已经创建了一个 WCF Web 服务项目,它将在 Web 服务进程(通常是 IIS)内运行,而不是在 Windows 窗体进程内运行,因此它无法访问 Windows 窗体中的静态类和属性中的任何数据过程。

听起来最简单的选择是将 WCF 服务托管在 Windows 窗体应用程序中。我不想详细介绍如何执行此操作,因为网络上已经有许多可用的资源(而且我很难声称自己是专家!),但您可能想尝试以下文章作为起点: