如何获得不过滤或不做任何事情的空规范?

问题描述

我有一个基本控制器,它应该返回一个对象列表(并将它们从 DTO 映射到业务)

如果子控制器决定应用规范(过滤或包含某些内容),它可以通过覆盖 GetSpecification() 方法来实现。

认情况下,在基类中我不想过滤对象。

[Route("api/[controller]")]
[ApiController]
public class BaseApiController<TBusinessModel,TApiModel,TBaseRepository> : BaseController<TBaseRepository>
                         where TBusinessModel   : BaseEntity
                         where TBaseRepository  : IBaseRepository
{
    public BaseApiController(TBaseRepository repository,IMapper mapper) : base(repository,mapper)
     { }

     // GET: api/Bars
     [HttpGet]
     public virtual async Task<IActionResult> List()
     {
        var spec = GetSpecification();
        var items = await _repository.ListAsync<TBusinessModel>(spec);
        var apiItems = _mapper.Map<List<TApiModel>>(items);                
        return Ok(apiItems);
     }

     protected virtual ISpecification<TBusinessModel> GetSpecification() 
     {
     // how to get an empty specification that does not filter or do something?
            return new Specification<TBusinessModel>(); 
      }
}

我使用 ardalis specifications,但它可以是任何通用的 IQueryable 东西...

实际上它说:

enter image description here

错误 CS0144 无法创建抽象类型的实例或 接口'规格'

解决方法

错误信息就够了,你不能实例化接口或抽象类。那是因为它没有任何逻辑。详情可以参考这个document

如果你想创建一个新的 Specification 类,我建议你可以尝试使用 SpecificationBuilder 类。

关于如何使用它的更多细节,你可以参考这个github link.

,

具有空规范是完全有效的构造。一旦评估将返回所有记录。在下面的例子中,它将返回所有客户

public class CustomerSpec : Specification<Customer>
{
    public CustomerSpec()
    {
    }
}

但是,这里的问题不是空规范。您正在尝试添加另一层抽象,并尝试直接实例化 Specification<T>Specification 是一个抽象类,因此您将无法创建实例。如果您渴望实现该基础架构,只需添加您自己从 Specification<T> 继承的基类,然后将其用作应用中所有其他规范的基础。

注意:我们使类抽象,正是为了阻止用户这样做:) 但是,请确保您可以继续以这种方式使用它。

public class AppSpecification<T> : Specification<T>
{

}
,

最后,由于提供的库中不存在像空规范这样的东西,我自己创建了它:

public class EmptySpecification<T> : Specification<T>
{
    public EmptySpecification()
    {
        // does nothing
    }
}

然后在 BaseController 中使用(最后几行):

[Route("api/[controller]")]
[ApiController]
public class BaseApiController<TBusinessModel,TDto,TBaseRepository> : BaseController<TBusinessModel,TBaseRepository>
    where TBusinessModel : BaseEntity
    where TBaseRepository : IBaseRepository
{
    public BaseApiController(TBaseRepository repository,IMapper mapper) : base(repository,mapper) { }

    [HttpGet]
    public virtual async Task<IActionResult> List()
    {
        var spec = ListSpecification();
        var items = await _repository.ListAsync<TBusinessModel>(spec);
        var apiItems = ToDto(items);
        return Ok(apiItems);
    }

    protected virtual ISpecification<TBusinessModel> ListSpecification()
    {
        return new EmptySpecification<TBusinessModel>();
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...