2009-09-30 2 views
1

질문 :
이 가능합니다 (자동)는 Visual Studio를 통해 생성 된 자동 생성 된 도메인 객체의 기본 클래스를 직접 변경하지 않고, 기능의 웹 참조 추가 ' References.cs 수정?웹 서비스 참조 엔터티의 기본 클래스를 자동 생성 지정

배경 :
우리는 웹 서비스에 대한 참조를 추가합니다 (Visual Studio를 통해 기능 '웹 참조 추가'), 클래스의 숫자가 자동으로 생성됩니다. 이 문서는 프록시 객체 (예 : MyServiceSoapClient) 및 자동 생성 도메인 객체 (예 : CustomerInfo)를 나타냅니다. 나는 다음의 라인을 따라 뭔가 할 경우

그래서 :

MyServiceSoapClient client = new MyServiceSoapClient(); 
CustomerInfo cust = client.GetCustomer("John Smith"); 

을 나는 다양한 속성 등으로 CustomerInfo 객체를 다시 얻을 것이다, 모든 멋지게 서버가 반환 어떤 XML로 직렬화.

문제가 ...
내가 '밥 딜런'에 CUST 개체의 Name 속성의 값을 변경 말할 수 있습니다.
이상한 점은, 기본 클래스에 지속적으로 제공되는 INotifyPropertyChanged.PropertyChanged 이벤트를 트래핑하여 변경 사항을 추적하면 ServiceEntity라는 기본 클래스를 갖고 싶습니다. 객체가 서비스에서 가져온 이후 변경되었습니다. 동기화 상태가 몇 상황에 기록 될 필요로

솔루션을
아래의 대답은 좋은 일이지만

, 우리는 약간 다른 접근 방식 ...
했다, 그것은 추가하는 것이 더 의미가 만든 Generic 클래스를 통한 추적 추적을 통해 필요할 때 언제든지 사용할 수 있습니다.

는 인터페이스 :

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(); 
} 

이 클래스 :

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 
} 

확장 방법 :을 통해 생성

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 
    }; 
} 
+0

단 제목을 수정하지 않아도 답변을 선택하면 충분하다는 것을 알 수 있고 사람들이 검색 할 때 더 쉽게 만들 수 있습니다. – blowdart

답변

1

클라이언트 프록시 클래스 비주얼 스튜디오의
다음은 예를 들어 제네릭 클래스 및 인터페이스의 웹 참조 기능이 내장되어 있습니다. 닷넷 프레임 워크의 wsdl.exe utility. 생성 될 때 출력은 공용 부분 클래스를 생성합니다. 자동 생성 된 출력을 수정하는 대신 구현하려는 이벤트 코드를 추가하는 다른 클래스 코드를 다른 파일에 제공 할 수 있습니다.

물론 각 개체에 대해 유사한 코드를 구현해야합니다. 소스 서비스에 따라 상속하는 모든 객체에 대해 단일 구현을 제공하기 위해 SoapHttpClientProtocol (또는 객체를 나타내는 프로토콜 기본 클래스를 확장)을 조사 할 수 있습니다. AOP을 사용하지 않으면 이것이 가능하지 않을 수 있습니다. 따라서 마일리지가 다를 수 있습니다.

+0

그건 실제로 아주 좋은 생각입니다. 그러나 우리는 PropertyChanged 이벤트 (INotifyPropertyChanged 인터페이스에서)에 반응하는 Generics 기반 클래스와 SyncObject 을 생성하는 일반 확장 메서드를 구현하여이 문제를 해결했습니다. 코드를 깨끗하게 유지하고 명시 적으로 필요로 할 때 동기화 데이터를 모니터링하는 데만 사용할 수있는 이점이 있습니다. 도움 주셔서 감사합니다. – Dan

+0

구조에 제네릭! 나는 그 전략을 더 좋아한다. EF 클래스를 효과적으로 래핑하는 것은 어려울 수 있습니다. – jro

+0

나는 이것을 시험해보기 위해 모든 노력을 기울 였지만 생성 된 클래스 *가 명시 적으로 객체에서 상속 받기 때문에 클래스가 확장 될 수는 있지만 다른 기본 클래스를 제공 할 수는 없기 때문에 나에게 도움이되지 않는다. 물었다 (그리고 내가해야 할 일). –

관련 문제