Giter Site home page Giter Site logo

Expose Top or Take about specification HOT 10 CLOSED

ardalis avatar ardalis commented on May 12, 2024
Expose Top or Take

from specification.

Comments (10)

fiseni avatar fiseni commented on May 12, 2024 1

This is implemented. If no one has additional comments, we may close the issue.

from specification.

fiseni avatar fiseni commented on May 12, 2024

Hey @ovation22 ,

If I understood correctly, you want to expose Take in the specification? You want to use Query.Take(4), instead of Query.Paginate(0, 4) ?

What would be the benefit actually? Not writing the 0?
Implementation wise, not hard to add. But, we have to ensure that Paginate() and Take() won't be used within the same specification, since it will overwrite the values. And that might add to the confusion.

from specification.

ardalis avatar ardalis commented on May 12, 2024

It's a good point about the two being exclusive of one another. @ovation22 and I were discussing this Friday and my first thought was that it would be more intuitive to offer a .Take directly rather than having to "page" to do it. Conceptually to me at least, I don't think about paging as a way to get "Top X Rows/Records". Under the covers I know paging uses Skip/Take but it still seems like a bit of a hack to have to go through the Paging abstraction just to take advantage of this fact.

It shouldn't be too hard for us to support Take or Paginate, and throw if both are used, right?

from specification.

fiseni avatar fiseni commented on May 12, 2024

Not a problem to implement. I was just thinking how to provide a consistent API. Not a huge fan of overlapping functionalities :)
If we think twice, Paginate is just a dummy wrapper and made sense in the legacy API, but now that we have LINQ alike structure, we may be more verbose and expose Top and Skip directly. For now we can support both ways, and decorate the Paginate as obsolete. In the future we'll remove it completely. Makes sense?

But, I have a feeling we misunderstood @ovation22. He might want to get top records regardless of the specification (for any spec). If this is a case, this can be done in your repository implementation.
We provide RepositoryBase generic repository ready to use. It's an abstract one, so anyway you will have to derive from it. You could do something like this in your repo.

public interface IRepository<T> : IRepositoryBase<T> where T : class
{
    Task<List<T>> GetTopAsync(ISpecification<T> specification, int take);
    Task<List<TResult>> GetTopAsync<TResult>(ISpecification<T, TResult> specification, int take);
}

public class Repository<T> : RepositoryBase<T>, IRepository<T> where T : class
{
    protected readonly TestDbContext dbContext;

    public Repository(TestDbContext dbContext) : base(dbContext)
    {
        this.dbContext = dbContext;
    }

    public async Task<List<T>> GetTopAsync(ISpecification<T> specification, int take)
    {
        return await ApplySpecification(specification).Take(take).ToListAsync();
    }

    public async Task<List<TResult>> GetTopAsync<TResult>(ISpecification<T, TResult> specification, int take)
    {
        return await ApplySpecification(specification).Take(take).ToListAsync();
    }
}

PS. I just noticed ApplySpecification is a private method. We'll make that protected, no harm of exposing it.

from specification.

ovation22 avatar ovation22 commented on May 12, 2024

I was specifically referencing using Top/Take in a Specification, but I appreciate the option with the IRepository.

Giving it more thought over the weekend I was thinking along those lines same lines as you mention @fiseni if it would make sense to expose Take and Skip and deprecating Paginate. Makes sense to me.

from specification.

ardalis avatar ardalis commented on May 12, 2024

One of the key benefits of the Specification pattern IMO is that it helps prevent the need for repository implementations to have tons of different methods. If we can avoid adding more methods to repository by allowing fewer methods to do the same thing using a specification, I think we should do that. I also don't want to require devs to have to use our base repository just because they want to use specifications (as that will hurt adoption).

So, I think your original idea works:

Not a problem to implement. I was just thinking how to provide a consistent API. Not a huge fan of overlapping functionalities :)
If we think twice, Paginate is just a dummy wrapper and made sense in the legacy API, but now that we have LINQ alike structure, we may be more verbose and expose Top and Skip directly. For now we can support both ways, and decorate the Paginate as obsolete. In the future we'll remove it completely. Makes sense?

I'm still not sure I want to drop Paginate, since I like the naming of it (it's a higher level abstraction that covers up the low level skip/take details) but I agree it's not great design to have 2 ways to do the same thing.

from specification.

ardalis avatar ardalis commented on May 12, 2024

Giving it more thought over the weekend I was thinking along those lines same lines as you mention @fiseni if it would make sense to expose Take and Skip and deprecating Paginate. Makes sense to me.

Sounds like we all agree. Add Take/Skip to specification and mark Paginate obsolete.

from specification.

fiseni avatar fiseni commented on May 12, 2024

I do share your opinion regarding the repositories. I didn't mean to provide the functionality through the repo, or enforce it in any way. It's just an example how users can implement such thing in their code base, in their repo (cos that's the only way you can get such general Top functionality).

I'm free for the next 30 mins, I'll do the changes now.

from specification.

ardalis avatar ardalis commented on May 12, 2024

Ok so all I need to do if it looks good is publish a new point release, yes?

from specification.

fiseni avatar fiseni commented on May 12, 2024

Yes, I think so.
I don't think we have some breaking changes, but you might want to go through the history and cross check. There is a comment on the last commit too.

Other than that, tests should be refactored. It's in my backlog too, if I find time in the next period, I'll try to go through that.

from specification.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.