2011-02-18 18 views
7

Tengo una aplicación existente que ahora tiene el requisito de interactuar desde un dispositivo móvil. El dispositivo móvil tiene una conexión wifi y se conectará a la PC que aloja la aplicación principal en una LAN. El dispositivo móvil simplemente necesita agregar/editar/buscar/eliminar objetos que la aplicación principal está manteniendo. La aplicación principal ya encapsula su funcionalidad en algunas clases de repositorio simples.¿Agregar el servicio WCF a la aplicación existente?

Creo que el enfoque sería agregar un servicio WCF a la aplicación principal que expone un conjunto de métodos que el dispositivo móvil puede invocar. Sin embargo, he buscado WCF hoy e intenté configurar una aplicación de ejemplo, pero cuando llamé a los métodos WCF no puedo acceder a ningún dato, siento que el servicio WCF se está ejecutando en su propio dominio de aplicación y, como tal, no tiene acceso a las mismas clases estáticas en la aplicación principal.

Si configuro un proyecto de servicio WCF en VS 2008/2010, ¿cómo puedo ejecutarlo bajo el mismo dominio de aplicación que la aplicación WinForms principal, para que una aplicación remota en la LAN pueda comunicarse con él para obtener datos del solicitud.

A continuación es mi muestra 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" }); 
     } 
    } 
} 

Lo que necesito de un servicio WCF, es el acceso a TestDataProject.DataStore.GetInstance();

Editar

he conseguido esto mediante

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 
    } 
} 

Con app.config que contiene

<?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> 

Entonces podría usar cliente de prueba WCF en la url http://localhost:8001/MetadataSample

El problema principal que sufrí desde que mi Servicio comenzó automáticamente, esto se puede desactivar en VS2010 mediante una configuración de proyecto. Y el otro tema fue UAC, estudio visual dada fue que no va a ser un administrador del depurador no pudo albergar un servicio, éste se fijó mediante la adición de un archivo que contiene 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> 
+0

suena como por "servicio WCF" es posible que se refiere a un servicio WCF web que se ejecuta en el contexto de IIS/servidor web.¿Su servicio WCF que ha creado definitivamente se ejecuta dentro del proceso de formularios de Windows? – Justin

+0

@Kragen, no creo que sea, que tal vez el problema. Creé un nuevo proyecto WCF en Visual Studio (Archivo -> Nuevo -> Proyecto -> Aplicación de servicio WCF) En los contactos de servicio definí un conjunto de métodos de prueba, pero no devuelven los mismos datos que contiene el formulario. Form tiene acceso a 5 objetos en un repositorio, pero el "mismo" repositorio tiene 0 objetos para el servicio WCF. El repositorio se accede a través de GetInstance para garantizar que tengan la misma referencia. – JonWillis

Respuesta

4

Ha creado un proyecto de servicio web WCF, que se ejecutará dentro del proceso del servicio web (normalmente IIS), no dentro del proceso de formularios de Windows y no tendrá acceso a datos en clases y propiedades estáticas en el proceso de Windows Forms.

Parece que su opción más simple es alojar el servicio WCF dentro de su aplicación de formularios de Windows. No quiero entrar en demasiados detalles sobre cómo hacerlo, ya que hay una cantidad de recursos ya disponibles en la web (¡y no puedo decir que sea un experto!), Pero es posible que desee probar el siguiente artículo como punto de partida:

+0

Tendré una lectura en el enlace y actualizaré la pregunta. He leído unos cuantos tutoriales WCF hoy, ¿tal vez me apresuré a hacerlo rápido? – JonWillis

+0

No me dio una solución funcional, pero he logrado juntar algo tomando partes de ese enlace y otros tutoriales. El término que necesitaba encontrar eran servicios WCF autohospedados. – JonWillis

2

servicios WCF se despliegan en el mismo ensamblar como el resto de la aplicación y debería poder acceder a cualquier clase en él. Tal vez has usado un espacio de nombres diferente. Si este es el caso, use un nombre completamente calificado o una declaración de uso.

Cuestiones relacionadas