Question

Nous appliquerons tous nos domaines d'objets à mettre en œuvre 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();
    }
  }
}

Lorsque nous exposons ces objets de domaine par WCF, le service généré suivant exige une modification post-mise à jour pour compiler.

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

Toutes les idées sur la façon de maintenir l'exigence de GetHashCode, mais supprimer l'exigence de tout code sur le client (comme une mise à jour ou en tant que classes partielles)?

Était-ce utile?

La solution

Si vous avez vraiment besoin que tous les consommateurs C # de votre utilisation des services WCF les mêmes modèles avec code d'origine dans le tact puis utilisez la fonction « Ajouter un service de référence » « Les types de réutilisation dans des assemblages référencés » de l'outil. Assurez-vous de briser vos modèles / contrats / interfaces en un seul ensemble avec aucun autre code de mise en œuvre en elle qui sert une assemblée « définition » partagée. Marquer cette assemblée comme celle des types de réutilisation à partir de quand l'outil « Ajouter un service de référence » génère votre code proxy client.

En outre, juste un avertissement proactif: simplifier les choses pour vous-même en ayant un seul client de service « officiel » C # mise en œuvre pour votre service. Ne pas ajouter d'autres mandataires de référence de services redondants générés par Visual Studio pour chaque projet qui nécessite une connectivité avec votre service.

EDIT:

Parlant de son expérience personnelle récente, ayant conçu un système modulaire, API de service activé, permettez-moi de fournir des conseils plus généraux sur le thème de la modularité en ce qui concerne non seulement pour les services WCF, mais la conception globale.

Dans notre système, nous avons fait ce que je propose ci-dessus dans la création d'un « Définition » ensemble qui contient des objets seulement marqué comme [DataContract]:. Objets de domaine, modèles, contrats de données, tout ce que vous aimez se référer à eux comme

Dans c'est assemblée aussi une collection d'interfaces référentiel qui définit des méthodes uniquement en termes de ces objets de domaine. Il y a aussi l'identificateur fortement typé struct définis dans cet ensemble qui sont utilisés pour les valeurs attente d'identité pour chaque modèle puisque ces modèles sont la base de données a persisté et chacun a une colonne d'identité. En utilisant struct qui ints wrap de cette manière est préférable d'utiliser int lui-même puisque maintenant nous obtenons l'analyse sémantique assistée par le compilateur, à savoir Model1ID n'est pas convertible en Model2ID car ils représentent sémantiquement deux domaines différents en dépit du fait que les deux domaines sont représentables par le type de int .

Quels sont les moteurs de la modularité est la définition de ces interfaces référentiel. La classe de mise en œuvre du service WCF implémente simplement toutes les interfaces requises, de même avec la classe d'implémentation client de service WCF, la base de données référentiel classe d'implémentation, le proxy de mise en cache classe d'implémentation, l'invocation méthode classe d'implémentation de l'exploitation forestière, etc. Tous béton cours de mise en œuvre existent dans d'autres ensembles, à savoir dans l'assemblée « Définition », qui contient les interfaces et modèles. Ces classes implémentent les interfaces et apparaissent au code de la consommation comme le même.

La clé est de garder votre API code de la consommation agnostique des classes d'implémentation spécifique et uniquement référence aux interfaces. Les modèles eux-mêmes sont aussi simples conteneurs de données sans mise en œuvre de la logique métier trouvé en leur sein. Je crois que ce modèle est appelé anémique, mais pour moi « anémique » a une connotation négative, donc je ne aime pas à utiliser ce terme pour décrire cette conception.

Ce que vous obtenez est code de la consommation mise en œuvre de la logique métier qui ne se soucie pas si elle parle à un service WCF ou directement à une base de données, ou que la mise en cache est mis en œuvre de façon transparente, ou que vos invocations de méthode sont en cours d'enregistrement, ou quoi que d'autres utilisations proxy que vous pouvez trouver.

En résumé, la conception d'interfaces et de rendre votre vie plus facile pour vous-même. Mais seulement faire cela si vous êtes confiant dans votre capacité à la pratique retenue. Dans notre système que je CONÇU, nous avons T4 modèles qui génèrent la quasi-totalité du code passe-partout qui vient avec les services WCF au point où tout ce que nous devons faire est de définir manuellement le modèle, la conception de l'interface, et d'écrire le code d'accès de base de données . La façade de WCF est livré gratuitement avec un simple clic droit et « Run Custom Tool » sur les modèles T4. J'aime cela. :)

Autres conseils

Fixer l'espace de noms sur votre classe partielle. Vous devrez peut-être modifier les attributs et l'héritage.

namespace DCS2000.IDCardExclude.UI.IdCardManagerServiceReference
{
  [Serializable]
  [DataContract]
  public partial class IdCard : DomainObject
  {
    public override int GetHashCode()
    {
        return EffDte.GetHashCode();
    }
  }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top