-2

我有一个基本控制器,它应该返回一个对象列表(并将它们从 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 规范,但它可以是任何通用IQueryable的东西......

实际上它说:

在此处输入图像描述

错误 CS0144 无法创建抽象类型或接口“规范”的实例

4

3 回答 3

0

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

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

有关如何使用它的更多详细信息,您可以参考此github 链接。

于 2021-02-02T03:12:36.567 回答
0

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

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

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

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

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

}
于 2021-02-02T12:55:35.200 回答
0

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

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

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

[Route("api/[controller]")]
[ApiController]
public class BaseApiController<TBusinessModel, TDto, TBaseRepository> : BaseController<TBusinessModel, TDto, 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>();
    }
}
于 2021-02-02T23:18:48.627 回答