Pregunta

Estamos haciendo cumplir todos nuestros objetos de dominio para implementar GetHashCode.

namespace Core
{
  [Serializable]
  public abstract class DomainObject
  {
    public abstract override int GetHashCode();
  }
}

namespace Entity.Domain
{
  [Serializable]
  [DataContract]
  public partial class IdCard : DomainObject
  {
    private System.Int32 _effDte;

    [DataMember]
    public virtual System.Int32 EffDte
    {
        get { return _effDte; }
        set { _effDte = value; }
    }

    public override int GetHashCode()
    {
        return EffDte.GetHashCode();
    }
  }
}

Cuando exponemos estos objetos de dominio a través de WCF, el siguiente servicio generado está requiriendo una modificación posterior a la actualización para compilar.

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.3053
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace IdCardManagerServiceReference {
using System.Runtime.Serialization;
using System;


[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="IdCard", Namespace="http://schemas.datacontract.org/2004/07/Entity.Domain")]
[System.SerializableAttribute()]
public partial class IdCard : Core.DomainObject, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged { 
    [System.NonSerializedAttribute()]
    private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

    [System.Runtime.Serialization.OptionalFieldAttribute()]
    private int EffDteField;

    [global::System.ComponentModel.BrowsableAttribute(false)]
    public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
        get {
            return this.extensionDataField;
        }
        set {
            this.extensionDataField = value;
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute()]
    public int EffDte {
        get {
            return this.EffDteField;
        }
        set {
            if ((this.EffDteField.Equals(value) != true)) {
                this.EffDteField = value;
                this.RaisePropertyChanged("EffDte");
            }
        }
    }
}

¿Alguna idea sobre cómo mantener el requisito de GetHashCode, pero eliminar el requisito de cualquier código en el cliente (como una actualización o como clases parciales)?

¿Fue útil?

Solución

Si realmente necesita que todos los consumidores de C # para el uso por el servicio WCF los mismos modelos con código original en el tacto a continuación, utilizar los "tipos reutilización en referencia a las asambleas" la opción "Agregar referencia de servicio" de la herramienta característica. Asegúrese de romper sus modelos / contratos / interfaces en un solo conjunto con ningún otro código de implementación en el mismo que sirve como una "definición" compartida montaje. Marcar este montaje como el de tipos de reutilización de cuando la función "Agregar referencia de servicio" genera el código de proxy de cliente.

Además, sólo una advertencia proactiva: Simplificar las cosas por sí mismo al tener una sola aplicación "oficial" C # servicio al cliente para su servicio. No añadir proxies de referencia de servicios redundantes generados por Visual Studio para cada proyecto que requiere conectividad con su servicio.

EDIT:

Hablando desde la experiencia personal reciente, después de haber diseñado una API modular, el servicio habilitado, me permite proporcionar asesoramiento más general sobre el tema de la modularidad en lo que respecta no sólo a los servicios WCF, pero el diseño general.

En nuestro sistema, hemos hecho lo que he sugerido más arriba en la creación de un único "Definición" asamblea que sólo contiene objetos marcada como [DataContract]:. Objetos de dominio, modelos, contratos de datos, lo que quiera hacer referencia a ellos como

En este montaje es también una colección de interfaces de repositorio que define métodos únicamente en términos de estos objetos de dominio. También hay estructuras de identificador fuertemente-mecanografiadas definidos en este montaje que se utilizan para los valores de identidad de retención por cada modelo ya que estos modelos son la base de datos persistido y cada uno tiene una columna de identidad. El uso de estructuras que ints de envoltura de esta manera es preferible al uso de int sí mismo ya que ahora obtenemos análisis semántico compilador asistida, es decir Model1ID no es convertible a Model2ID ya que semánticamente representan dos dominios diferentes a pesar del hecho de que ambos dominios son representable por el tipo int .

Lo que impulsa la modularidad es la definición de estas interfaces de repositorio. La clase de implementación de servicio WCF simplemente implementa todas las interfaces necesarias, de manera similar con la clase de servicio WCF implementación del cliente, la clase de implementación repositorio de base de datos, la clase de implementación de almacenamiento en caché de proxy, la invocación clase de implementación de la tala método, etc. Todo el hormigón existen clases de implementación de otros conjuntos, es decir, no en la "definición" conjunto que contiene las interfaces y modelos. Estas clases implementan las interfaces y parece que el código de consumo como el mismo.

La clave es mantener el código del consumidor API agnóstico de las clases de implementación específica y sólo hacer referencia a las interfaces. Los modelos mismos se mantienen como contenedores de datos simples con ninguna implementación lógica de negocio se encuentran dentro de ellos. Creo que este patrón se conoce como anemia, pero a mí "anémica" tiene connotaciones negativas por lo que no me gusta utilizar ese término para describir este diseño.

Lo que se obtiene es el código del consumidor implementar la lógica de negocio que no le importa si está hablando con un servicio WCF o directamente a una base de datos o el almacenamiento en caché que se está aplicando a la perfección, o que sus invocaciones de métodos se está registrando, o lo que sea otros usos proxy que pueden ocurrir.

En resumen, el diseño de interfaces y hacer la vida más fácil para usted mismo. Pero sólo hacer esto si se tiene la certeza en su capacidad para la práctica auto-control. En nuestro sistema, que he diseñado, tenemos T4 plantillas que generan casi todo el código estándar que viene junto con servicios WCF al punto donde todo lo que tenemos que hacer de forma manual es definir el modelo, el diseño de la interfaz, y escribir el código de acceso de base de datos . La fachada WCF viene gratis con un simple clic derecho y "Herramienta personalizada Ejecutar" en las plantillas T4. Me encanta. :)

Otros consejos

Fijar el espacio de nombres en su clase parcial. Es posible que tenga que ajustar los atributos y la herencia.

namespace DCS2000.IDCardExclude.UI.IdCardManagerServiceReference
{
  [Serializable]
  [DataContract]
  public partial class IdCard : DomainObject
  {
    public override int GetHashCode()
    {
        return EffDte.GetHashCode();
    }
  }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top