繁体   English   中英

继承自Passed Type Parameter成员的泛型Abstract类

[英]Generic Abstract class who inherits members from Passed Type Parameter

我正在尝试找出一种抽象适配器逻辑的方法。 我想拥有一个通用抽象类,该类继承自传递给它的成员。

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首选适配器基础或代理作为适配器基础的代理,这将为我处理所有这些逻辑。

有谁知道我可以抽象这个逻辑或变通的方法,所以我不必手动将这个逻辑应用于每个适配器?

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

这是完整的界面:

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

}

唯一的缺点是,现在您的服务与硬依赖性相关

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM