Question:
Est-il possible de (automatiquement) changer la classe de base des objets de domaine générés automatiquement créés par Visual Studio « Ajouter une référence Web » fonctionnalité, sans manuellement modifier References.cs?Spécifiez Web Service de référence AUTOGÉNÉRÉ classe de base Entité
Contexte:
Lorsque l'on ajoute une référence à un service Web (via Visual Studio 'Ajouter une référence Web' fonctionnalité), un certain nombre de classes sont générées automatiquement. Les thèses représentent un objet proxy (par exemple un MyServiceSoapClient) et un certain nombre d'objets de domaine générés automatiquement (par exemple, un CustomerInfo).
Donc, si je fais quelque chose le long des lignes de ce qui suit:
MyServiceSoapClient client = new MyServiceSoapClient();
CustomerInfo cust = client.GetCustomer("John Smith");
Je vais revenir un objet CustomerInfo avec diverses propriétés etc, joliment désérialisée de tout le serveur XML retourné.
Le problème est ...
Disons que je change la valeur de la propriété Nom de l'objet Cust à « Bob Dylan ».
Idéalement, je voudrais avoir une classe de base appelée ServiceEntity qui suivra si des changements ont été faits (en piégeant l'événement INotifyPropertyChanged.PropertyChanged fourni de façon continue dans la classe de base), pour fournir une propriété 'Dirty' indiquant que le l'objet a changé depuis qu'il a été récupéré du service.
La solution
Bien que la réponse ci-dessous est un bon, nous avons pris une approche légèrement différente ...
Comme l'état de synchronisation ne doit être enregistré dans quelques situations, il était plus logique d'ajouter synchroniser le suivi à travers une classe générique, afin que nous puissions l'utiliser au fur et à mesure des besoins.
Voici un exemple de classe générique et de l'interface:
Interface:
public interface ISyncEntity
{
/// <summary>
/// Gets or Sets the Entity Sync State
/// </summary>
[XmlIgnore]
[SoapIgnore]
EntitySyncState SyncState { get; set; }
/// <summary>
/// Flag for deletion
/// </summary>
void DeleteOnSync();
/// <summary>
/// Flag for Creation
/// </summary>
void CreateOnSync();
}
Classe:
public class SyncEntity<TEntity> : ISyncEntity
{
/// <summary>
/// Backing Field for Entity Property
/// </summary>
private TEntity _entity;
/// <summary>
/// Gets or Sets the Entity in question
/// </summary>
public TEntity Entity
{
get { return _entity; }
set { OnEntityChange(value); }
}
/// <summary>
/// Invoked when a Property on the Entity is changing
/// </summary>
/// <param name="entity"></param>
protected void OnEntityChange(TEntity entity)
{
// Detach the property change event handler from the previous entity?
if (_entity is INotifyPropertyChanged)
(entity as INotifyPropertyChanged).PropertyChanged -= OnPropertyChange;
// Set backing field
_entity = entity;
// Implements INotifyPropertyChanged?
if (entity is INotifyPropertyChanged)
(entity as INotifyPropertyChanged).PropertyChanged += OnPropertyChange;
// Set the Sync State
SyncState = EntitySyncState.Unchanged;
}
/// <summary>
/// Fired when a property in the entity changes
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void OnPropertyChange(object sender, PropertyChangedEventArgs e)
{
// If a delete or create is already pending, don't worry about the update!
if (SyncState == EntitySyncState.Unchanged)
SyncState = EntitySyncState.UpdatePending;
}
#region Sync Framework Members
[XmlIgnore]
[SoapIgnore]
public EntitySyncState SyncState
{
get;
set;
}
public void DeleteOnSync()
{
SyncState = EntitySyncState.DeletePending;
}
public void CreateOnSync()
{
SyncState = EntitySyncState.CreatePending;
}
#endregion
}
Méthode d'extension:
public static SyncEntity<TEntity> ToSyncEntity<TEntity>(this TEntity source)
{
if (source == null)
throw new ArgumentException("Source cannot be null");
return new SyncEntity<TEntity>()
{
Entity = source
};
}
Dan vous n'avez pas à éditer votre titre pour dire qu'il est résolu, la sélection d'une réponse est suffisante et facilite la recherche de personnes – blowdart