Comments (5)
It's not advisable typically to try to combine specifications. That moves the logic of composing the query out of the specification (and domain model) and into the calling code (probably in another less testable part of the app).
In your case why not have one that takes in a status and an id in its constructor?
from specification.
In my case, I would have a method at my service like GetOpenOrdersByCustomer, and I would only use the specifications inside my method, I would not make the specs visible to the UI, for example.
I was trying to achieve the concat so that I wouldn't need to create one spec for Status, one for Customer, and one for both.
from specification.
Again, we don't have plans to add support for combining specs. Personally I would create 3 specs and if there were logic between them that you really didn't want to duplicate, I'd do something like reference the expression in question from a shared constant value. But more likely I would just create 3 independent specs. If I really wanted one super-flexible spec, I'd create one that took in Customer and Status, but allowed for either one (but not both) of them to be omitted. That, too, seems kind of a poor design, so again I'd probably go the 3 spec route. Sorry to not be more help.
from specification.
I understand, and I thank you for all the info you've provided me.
from specification.
I think I just did this. If there is any problem with this design, please let me know, this is a copy of my work.
using Ardalis.Specification;
namespace Domain.Abstraction.Specifications;
/// <summary>
/// Domain Specification interface
/// </summary>
/// <typeparam name="T">The type being queried against.</typeparam>
/// <remarks>You have to call <see cref="Build"/> method to build the query logic before using.</remarks>
public interface IDomainSpecification<T> : ISpecification<T>
{
/// <summary>
/// Whether the current query model is an unconditional query model
/// </summary>
/// <returns><see langword="true"/> if it's an unconditional query model, otherwise <see langword="false"/></returns>
bool IsPredicateLess() => !WhereExpressions.Any();
/// <summary>
/// build the query logic
/// </summary>
/// <remarks>In the case of multiple inheritance, the subclass must ensure that the implementation of the parent class is called in this method.
/// The order of calling the implementation of the parent class is determined according to the situation, and it is not necessary to call the implementation of the parent class first.Although the order in which query conventions are
/// constructed is not important it does not preclude the order being considered necessary in the new Ardalis.Specification package.
/// Under normal circumstances, the implementation of the parent class is called at the end, so that the query logic of the subclass will be constructed first</remarks>
void Build();
}
/// <summary>
/// Pagination specification
/// </summary>
/// <typeparam name="T">The type being queried against.</typeparam>
/// <remarks>You have to call <see cref="Build"/> method to build the query logic before using.</remarks>
public interface IPaginationSpecification<T> : IDomainSpecification<T>
{
}
public class CompanySpec : Specification<Company> , IDomainSpecification<Company>
{
private bool built;
public void Build()
{
// make sure it only build once.
if(built)
return;
//Do something before sub class build
PreBuild();
//Do something after sub class build
built = true;
}
/// <summary>
/// build query
/// </summary>
/// <remarks>make sure the implements are call the base <see cref="PreBuild"/>method</remarks>
protected virtual void PreBuild()
{
Query.Where(e => !e.Deleted);
}
}
public class CompanyPaginationSpec : CompanySpec, IPaginationSpecification<Company>
{
///<summary>
/// Page index begin with 1
///</summary>
public int PageIndex { get; }
public int PageSize { get; }
public CompanyPaginationSpec(int pageIndex, int pageSize)
{
PageIndex = pageIndex;
PageSize = pageSize;
}
protected override void PreBuild()
{
base.PreBuild();
Query.Skip(PageSize * (PageIndex - 1)).Take(PageSize);
}
}
CompanySpec
is an example class, you can create a common abstract class, it build the all the base entity or DTO query logic. the real entity or DTO implement this abstract class gets the base query logic.
I do not like call virtual method in the constructor, this may cause NullReferenceException. call virtual method in constructor need to make sure the sub class is not access its instance member in the override method.
@diegomodolo example updated.
from specification.
Related Issues (20)
- Request to multi-target EntityFramework6.csproj and include net6.0 HOT 3
- Query.Dstinct() HOT 1
- Update LangVersion to C# 10 or 11
- Update conventions and styling
- Update Sample projects
- Remove obsolete API
- Update pipelines.
- Including nullable/optional navigation property causes only non-nullable connected objects to be returned HOT 3
- Unable to apply Take() to a navigation property HOT 5
- Refactor and improve integration test fixtures.
- Why do the Update and Delete not returning anything? HOT 3
- Logging in the Package HOT 4
- Feature Request: Deletion of entities via specification HOT 5
- Shadow properties HOT 4
- Query to return anonymous type HOT 4
- Question: Can I some how join table "B" when my entity T does not have a navigation property to "B" ? HOT 2
- Expression Evaluation HOT 8
- Simplify Cache usage HOT 5
- DbSet<T>.WithSpecification together with ISpecification<T, TDestination> throws SelectorNotFoundException HOT 4
- Conceptual question about the ORM specific implementations HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from specification.