Generic Abstract class 从 Passed Type Parameter 继承成员

Generic Abstract class who inherits members from Passed Type Parameter

我正在尝试找出一种方法来抽象我的适配器逻辑。我想要一个从传递给它的成员继承的通用摘要 class。

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 像我的父 class 一样强制执行它。

如果有人想知道为什么或这里发生了什么,这个适配器基础应用于必须实现 DTO 接口属性的适配器,然后将附加逻辑应用于 getter 和设置以防止 id 篡改和做一些基本的设置逻辑。

如果我手动将此代码应用于每个适配器,则此代码工作正常,但我更喜欢适配器基础或代理而不是适配器基础,后者将为我处理所有这些逻辑。

有谁知道我可以抽象出这个逻辑的方法,或者解决方法,这样我就不必手动将这个逻辑应用到每个适配器?

对于那些想要答案的人,我找到了一个解决方案,但你可能不喜欢它。

这是完整界面:

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

}

唯一的缺点是现在您的服务依赖于硬依赖