2017-02-15 64 views
0

繼承成員,我試圖找出一種方法來抽象我的適配器邏輯。我想要有一個通用抽象類繼承自傳入它的成員。通用抽象類誰從傳遞類型參數

public interface IAdaptable<in TIEntity, in TIDTO, TDTO> 
    where TDTO : TIDTO 
{ 
    void Initialize(TIEntity entity); 
    TDTO ToDTO(); 
} 

public interface IAdaptable<in TIEntity, TDTO> : IAdaptable<TIEntity, TDTO, TDTO> 
{ 
} 

public abstract class AdapterBase<TEntity, TIDTO, TDTO> : IAdaptable<TEntity, TIDTO, TDTO>, TIDTO 
    where TDTO : TIDTO 
{ 
    protected TEntity entity; 

    public void Initialize(TEntity entity) 
    { 
     this.entity = entity; 
    } 

    public TDTO ToDTO() 
    { 
     return Mapper.Map<TIDTO, TDTO>(this); 
    } 
} 

此代碼不起作用,因爲您不能繼承傳入的泛型參數,即使id像我的父類一樣強制執行它。

因爲任何人想知道爲什麼或者這裏發生了什麼,這個適配器基礎被應用到必須實現DTO接口屬性的適配器上,然後額外的邏輯被應用到獲取器並設置以防止id篡改並且執行一些基本的設置邏輯。如果我手動將其應用到每個適配器,但ID喜歡適配器底座或代理的適配器基地將處理所有這個邏輯我

此代碼工作正常。

有誰知道的一種方法,我可以抽象這個邏輯,或解決,所以我沒有這樣的邏輯手動適用於每個適配器?

+0

我相信城堡動態代理是實現這一目標的唯一途徑,但我可能是錯的。 – inquisitive

+0

@inquisitive謝謝你的提示,我將調查那些是什麼 –

+0

你肯定這還是它的一個錯字:'公共抽象類AdapterBase :IAdaptable的 TIDTO'最後'TIDTO' – CodingYoshi

回答

0

對於那些你們誰想要的答案我已經找到了解決辦法,但你可能不喜歡它。

這是全接口:

public interface IAdaptable<in TIEntity, in TIDTO, TDTO> 
    where TDTO : TIDTO 
{ 
    bool IsInitialized { get; set; } 
    void Initialize(TIEntity entity); 
    TDTO ToDTO(TIDTO iEntityDTO); 
    void ApplyFrom(TIDTO entityDTO); 
} 

現在你可以創建連接座這樣的:

public class AdapterBase<TIEntity, TIDTO, TDTO> : IAdaptable<TIEntity, TIDTO, TDTO> 
    where TDTO : TIDTO 
{ 
    #region Consts 

    public const string FAILED_TO_INITIALIZE_ADAPTER_ERROR = "Failed to Initialize Adapter make sure you called the Initialize function"; 

    #endregion 

    #region Protected Members 

    protected TIEntity _entity; 

    #endregion 

    #region IAdaptable 

    public bool IsInitialized { get; set; } 

    public void Initialize(TIEntity entity) 
    { 
     this._entity = entity; 
     IsInitialized = true; 
    } 

    public void ApplyFrom(TIDTO entityDTO) 
    { 
     if (false == IsInitialized) 
     { 
      throw new Exception(FAILED_TO_INITIALIZE_ADAPTER_ERROR); 
     } 

     Mapper.Map(entityDTO, this); 

    } 

    public TDTO ToDTO(TIDTO adaptable) 
    { 
     if (false == IsInitialized) 
     { 
      throw new Exception(FAILED_TO_INITIALIZE_ADAPTER_ERROR); 
     } 

     return Mapper.Map<TIDTO, TDTO>(adaptable); 
    } 

    #endregion 
} 

現在你可以使用你的適配器通用的CRUD服務一樣,像這樣

public class AsyncCRUDService<TEntity, TIDTO, TDTO, TAdapter> : IAsyncCRUDService<TDTO> 
    where TDTO : TIDTO 
    where TEntity : class, new() 
    where TAdapter : class, TIDTO, IAdaptable<TEntity, TIDTO, TDTO> 
{ 
    protected DbContext _context; 
    protected TAdapter _adapter; 

    public AsyncCRUDService(DbContext context, TAdapter adapter) 
    { 
     this._context = context; 
     this._adapter = adapter; 
    } 

    public async virtual Task<TDTO> Get(object[] id) 
    { 
     var entity = await this._context.Set<TEntity>().FindAsync(id); 

     if (null == entity) 
     { 
      throw new InvalidIdException(); 
     } 
     return this.AdaptToDTO(entity); 
    } 

    protected virtual TDTO AdaptToDTO(TEntity entity) 
    { 
     this._adapter.Initialize(entity); 
     return this._adapter.ToDTO(this._adapter); 
    } 

} 

唯一的缺點是,現在你的服務與困難的依賴關係密切相關