├── docs
├── help.md
└── _config.yml
├── global.json
├── images
├── data.png
├── data-paginable.png
├── paginable-alpha.png
└── paginable-table.png
├── src
└── PaginableCollections
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── IPaginableRequest.cs
│ ├── IPager.cs
│ ├── IPaginableItem.cs
│ ├── IPagerItem.cs
│ ├── PaginableRequest.cs
│ ├── EmptyPaginable.cs
│ ├── PagerItem.cs
│ ├── PaginableItem.cs
│ ├── EnumerableExtensions.cs
│ ├── PaginableCollections.csproj
│ ├── StaticPaginable.cs
│ ├── StaticPager.cs
│ ├── QueryableBasedPaginable.cs
│ ├── IPaginable.cs
│ ├── PaginableExtensions.cs
│ └── Paginable.cs
├── tools
└── packages.config
├── samples
├── ConsoleAppDotNet45
│ ├── App.config
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── ConsoleAppDotNet45.csproj
├── ConsoleAppDotNetCore11
│ ├── ConsoleAppDotNetCore11.csproj
│ └── Program.cs
└── ConsoleAppDotNetCore20
│ ├── ConsoleAppDotNetCore20.csproj
│ └── Program.cs
├── tests
└── PaginableCollections.Tests
│ ├── StaticPagerTests.cs
│ ├── PaginableRequestTests.cs
│ ├── EmptyPaginableTests.cs
│ ├── PaginableCollections.Tests.csproj
│ ├── EnumerableStaticPaginableRequestTests.cs
│ ├── QueryablePaginableRequestTests.cs
│ ├── EnumerableQueryablePaginableTests.cs
│ ├── EnumerableStaticPaginableTests.cs
│ ├── StaticPaginableTests.cs
│ ├── QueryablePaginableTests.cs
│ └── PagerItemTests.cs
├── .gitattributes
├── appveyor.yml
├── LICENSE
├── README.md
├── CODE_OF_CONDUCT.md
├── PaginableCollections.sln
└── .gitignore
/docs/help.md:
--------------------------------------------------------------------------------
1 | test
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "2.1.400"
4 | }
5 | }
--------------------------------------------------------------------------------
/images/data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dataneek/paginable-collections/HEAD/images/data.png
--------------------------------------------------------------------------------
/src/PaginableCollections/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | [assembly: CLSCompliant(true)]
--------------------------------------------------------------------------------
/images/data-paginable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dataneek/paginable-collections/HEAD/images/data-paginable.png
--------------------------------------------------------------------------------
/images/paginable-alpha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dataneek/paginable-collections/HEAD/images/paginable-alpha.png
--------------------------------------------------------------------------------
/images/paginable-table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dataneek/paginable-collections/HEAD/images/paginable-table.png
--------------------------------------------------------------------------------
/tools/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/PaginableCollections/IPaginableRequest.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | public interface IPaginableRequest
4 | {
5 | int PageNumber { get; }
6 | int ItemCountPerPage { get; }
7 | }
8 | }
--------------------------------------------------------------------------------
/samples/ConsoleAppDotNet45/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/PaginableCollections/IPager.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | using System.Collections.Generic;
4 |
5 | public interface IPager
6 | {
7 | IEnumerable GetPages();
8 |
9 | int TotalPageCount { get; }
10 | int MaximumPageNumberCount { get; }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/PaginableCollections/IPaginableItem.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | public interface IPaginableItem
4 | {
5 | int ItemNumber { get; }
6 | int PageNumber { get; }
7 | int ItemCountPerPage { get; }
8 | }
9 |
10 | public interface IPaginableItem : IPaginableItem
11 | {
12 | T Item { get; }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/PaginableCollections/IPagerItem.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | public interface IPagerItem
4 | {
5 | int PageNumber { get; }
6 | int TotalPageCount { get; }
7 |
8 | bool IsFirstPage { get; }
9 | bool IsLastPage { get; }
10 |
11 | bool HasPreviousPage { get; }
12 | bool HasNextPage { get; }
13 | }
14 | }
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/StaticPagerTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Tests
2 | {
3 | using System.Linq;
4 | using Xunit;
5 |
6 | public class StaticPagerTest
7 | {
8 | [Fact]
9 | public void ShouldNotBeNull()
10 | {
11 | var sut = Enumerable.Range(1, 10).ToPaginable(1, 5).ToPager(2);
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/samples/ConsoleAppDotNetCore11/ConsoleAppDotNetCore11.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp1.1
6 | ConsoleAppDotNetCore
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/samples/ConsoleAppDotNetCore20/ConsoleAppDotNetCore20.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 | ConsoleAppDotNetCore
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/src/PaginableCollections/PaginableRequest.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | public class PaginableRequest : IPaginableRequest
4 | {
5 | public PaginableRequest(int pageNumber, int itemCountPerPage)
6 | {
7 | PageNumber = pageNumber;
8 | ItemCountPerPage = itemCountPerPage;
9 | }
10 |
11 | public int PageNumber { get; private set; }
12 | public int ItemCountPerPage { get; private set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/PaginableCollections/EmptyPaginable.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | using System.Linq;
4 |
5 | ///
6 | /// Represents an empty paginable collection.
7 | ///
8 | ///
9 | public class EmptyPaginable : StaticPaginable
10 | {
11 | public const int DefaultItemCountPerPage = 10;
12 |
13 | ///
14 | /// Create new empty paginable collection.
15 | ///
16 | public EmptyPaginable()
17 | : base(Enumerable.Empty(), 1, DefaultItemCountPerPage, 0)
18 | {
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/PaginableCollections/PagerItem.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | public class PagerItem: IPagerItem
4 | {
5 | public PagerItem(int pageNumber, int totalPageCount)
6 | {
7 | PageNumber = pageNumber;
8 | TotalPageCount = totalPageCount;
9 | }
10 |
11 | public int PageNumber { get; private set; }
12 | public int TotalPageCount { get; private set; }
13 |
14 | public bool IsFirstPage => PageNumber == 1;
15 | public bool IsLastPage => PageNumber >= TotalPageCount;
16 |
17 | public bool HasPreviousPage => PageNumber > 1;
18 | public bool HasNextPage => PageNumber < TotalPageCount;
19 | }
20 | }
--------------------------------------------------------------------------------
/src/PaginableCollections/PaginableItem.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | public class PaginableItem : IPaginableItem
4 | {
5 | private PaginableItem() { }
6 |
7 | public PaginableItem(T item, int itemNumber, int pageNumber, int itemCountPerPage)
8 | {
9 | Item = item;
10 | ItemNumber = itemNumber;
11 | PageNumber = pageNumber;
12 | ItemCountPerPage = itemCountPerPage;
13 | }
14 |
15 | public T Item { get; private set; }
16 | public int ItemNumber { get; private set; }
17 | public int PageNumber { get; private set; }
18 | public int ItemCountPerPage { get; private set; }
19 | }
20 | }
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | image: Visual Studio 2017
2 | version: '{build}'
3 | pull_requests:
4 | do_not_increment_build_number: true
5 | branches:
6 | only:
7 | - master
8 | nuget:
9 | disable_publish_on_pr: true
10 | build_script:
11 | - ps: .\build.ps1
12 | test: off
13 | artifacts:
14 | - path: .\artifacts\**\*.nupkg
15 | name: NuGet
16 | deploy:
17 | - provider: NuGet
18 | server: https://www.myget.org/F/neekgreen/api/v2
19 | api_key:
20 | secure: F+HOhtceWDrA8csKd3erzdsHZQDTiZyuZu1GxUF9cn6lQCi57c1A1Spz61jY6jMb
21 | skip_symbols: true
22 | on:
23 | branch: master
24 | - provider: NuGet
25 | name: production
26 | api_key:
27 | secure: LETsd+PTuBvLDx2FdbTtP/gbsYonG2uh/gT7BVG2ZNU1RZBZ7UNJ/uXlpB5/ztKv
28 | on:
29 | branch: master
30 | appveyor_repo_tag: true
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/PaginableRequestTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Tests
2 | {
3 | using FluentAssertions;
4 | using Xunit;
5 |
6 | public class PaginableRequestTests
7 | {
8 | [Fact]
9 | public void ShouldEqualPageNumber()
10 | {
11 | var expectedPageNumber = 2;
12 | var sut = new PaginableRequest(expectedPageNumber, 10);
13 |
14 | sut.PageNumber.ShouldBeEquivalentTo(expectedPageNumber);
15 | }
16 |
17 | [Fact]
18 | public void ShouldEqualItemCountPerPage()
19 | {
20 | var expectedItemCountPerPage = 12;
21 | var sut = new PaginableRequest(2, expectedItemCountPerPage);
22 |
23 | sut.ItemCountPerPage.ShouldBeEquivalentTo(expectedItemCountPerPage);
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/samples/ConsoleAppDotNet45/Program.cs:
--------------------------------------------------------------------------------
1 | namespace ConsoleAppDotNet45
2 | {
3 | using System;
4 | using System.Linq;
5 | using PaginableCollections;
6 |
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | var itemCountPerPage = 25;
12 | var pageNumber = 4;
13 |
14 | var paginable =
15 | Enumerable.Range(1, 200)
16 | .ToPaginable(pageNumber, itemCountPerPage);
17 |
18 | Console.WriteLine(string.Format("page number {0}", pageNumber));
19 | Console.WriteLine(string.Format("item count per page {0}", itemCountPerPage));
20 | Console.WriteLine(string.Join(",", paginable.Select(t => t.Item)));
21 | Console.WriteLine(string.Format("showing items {0} to {1} of {2}", paginable.FirstItemNumber, paginable.LastItemNumber, paginable.TotalItemCount));
22 | Console.ReadLine();
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/samples/ConsoleAppDotNetCore11/Program.cs:
--------------------------------------------------------------------------------
1 | namespace ConsoleAppDotNetCore
2 | {
3 | using System;
4 | using System.Linq;
5 | using PaginableCollections;
6 |
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | var itemCountPerPage = 25;
12 | var pageNumber = 4;
13 |
14 | var paginable =
15 | Enumerable.Range(1, 200)
16 | .ToPaginable(pageNumber, itemCountPerPage);
17 |
18 | Console.WriteLine(string.Format("page number {0}", pageNumber));
19 | Console.WriteLine(string.Format("item count per page {0}", itemCountPerPage));
20 | Console.WriteLine(string.Join(",", paginable.Select(t => t.Item)));
21 | Console.WriteLine(string.Format("showing items {0} to {1} of {2}", paginable.FirstItemNumber, paginable.LastItemNumber, paginable.TotalItemCount));
22 | Console.ReadLine();
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/samples/ConsoleAppDotNetCore20/Program.cs:
--------------------------------------------------------------------------------
1 | namespace ConsoleAppDotNetCore
2 | {
3 | using System;
4 | using System.Linq;
5 | using PaginableCollections;
6 |
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | var itemCountPerPage = 25;
12 | var pageNumber = 4;
13 |
14 | var paginable =
15 | Enumerable.Range(1, 200)
16 | .ToPaginable(pageNumber, itemCountPerPage);
17 |
18 | Console.WriteLine(string.Format("page number {0}", pageNumber));
19 | Console.WriteLine(string.Format("item count per page {0}", itemCountPerPage));
20 | Console.WriteLine(string.Join(",", paginable.Select(t => t.Item)));
21 | Console.WriteLine(string.Format("showing items {0} to {1} of {2}", paginable.FirstItemNumber, paginable.LastItemNumber, paginable.TotalItemCount));
22 | Console.ReadLine();
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/EmptyPaginableTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Tests
2 | {
3 | using FluentAssertions;
4 | using Xunit;
5 |
6 | public class EmptyPaginableTests
7 | {
8 | [Fact]
9 | public void ShouldEqualPageNumber()
10 | {
11 | var expectedPageNumber = 1;
12 | var sut = Paginable.Empty();
13 |
14 | sut.PageNumber.ShouldBeEquivalentTo(expectedPageNumber);
15 | }
16 |
17 | [Fact]
18 | public void ShouldEqualItemCountPerPage()
19 | {
20 | var expectedItemCountPerPage = EmptyPaginable.DefaultItemCountPerPage;
21 | var sut = Paginable.Empty();
22 |
23 | sut.ItemCountPerPage.ShouldBeEquivalentTo(expectedItemCountPerPage);
24 | }
25 |
26 | [Fact]
27 | public void ShouldEqualTotalItemCount()
28 | {
29 | var expectedTotalItemCount = 0;
30 | var sut = Paginable.Empty();
31 |
32 | sut.TotalItemCount.ShouldBeEquivalentTo(expectedTotalItemCount);
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/PaginableCollections.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.0
5 | PaginableCollections.Tests
6 | PaginableCollections.Tests
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/PaginableCollections/EnumerableExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | using System.Collections.Generic;
4 | using System.Linq;
5 |
6 | public static class EnumerableExtensions
7 | {
8 | public static IPaginable ToPaginable(this IEnumerable enumerable, int pageNumber, int itemCountPerPage)
9 | {
10 | return
11 | enumerable
12 | .AsQueryable()
13 | .ToPaginable(pageNumber, itemCountPerPage);
14 | }
15 |
16 | public static IPaginable ToPaginable(this IEnumerable enumerable, IPaginableRequest paginableRequest)
17 | {
18 | return
19 | enumerable
20 | .ToPaginable(paginableRequest.PageNumber, paginableRequest.ItemCountPerPage);
21 | }
22 |
23 | public static IPaginable ToPaginable(this IEnumerable enumerable, int pageNumber, int itemCountPerPage, int totalItemCount)
24 | {
25 | return new StaticPaginable(enumerable, pageNumber, itemCountPerPage, totalItemCount);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Nicholas Myers
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/EnumerableStaticPaginableRequestTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Tests
2 | {
3 | using System.Linq;
4 | using FluentAssertions;
5 | using Xunit;
6 |
7 | public class EnumerableStaticPaginableRequestTests
8 | {
9 | [Fact]
10 | public void ShouldEqualPageNumber()
11 | {
12 | var source = Enumerable.Range(10, 50);
13 | var expectedPageNumber = 2;
14 | var paginableInfo = new PaginableRequest(expectedPageNumber, 10);
15 |
16 | var sut = source.ToPaginable(paginableInfo);
17 |
18 | sut.PageNumber.ShouldBeEquivalentTo(expectedPageNumber);
19 | }
20 |
21 | [Fact]
22 | public void ShouldEqualItemCountPerPage()
23 | {
24 | var source = Enumerable.Range(11, 100);
25 | var expectedItemCountPerPage = 12;
26 | var paginableInfo = new PaginableRequest(2, expectedItemCountPerPage);
27 |
28 | var sut = source.ToPaginable(paginableInfo);
29 |
30 | sut.ItemCountPerPage.ShouldBeEquivalentTo(expectedItemCountPerPage);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/QueryablePaginableRequestTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Tests
2 | {
3 | using System.Linq;
4 | using FluentAssertions;
5 | using Xunit;
6 |
7 | public class QueryablePaginableRequestTests
8 | {
9 | [Fact]
10 | public void ShouldEqualPageNumber()
11 | {
12 | var source = Enumerable.Range(10, 50).AsQueryable();
13 | var expectedPageNumber = 2;
14 | var paginableInfo = new PaginableRequest(expectedPageNumber, 10);
15 |
16 | var sut = source.ToPaginable(paginableInfo);
17 |
18 | sut.PageNumber.ShouldBeEquivalentTo(expectedPageNumber);
19 | }
20 |
21 | [Fact]
22 | public void ShouldEqualItemCountPerPage()
23 | {
24 | var source = Enumerable.Range(11, 100).AsQueryable();
25 | var expectedItemCountPerPage = 12;
26 | var paginableInfo = new PaginableRequest(2, expectedItemCountPerPage);
27 |
28 | var sut = source.ToPaginable(paginableInfo);
29 |
30 | sut.ItemCountPerPage.ShouldBeEquivalentTo(expectedItemCountPerPage);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/EnumerableQueryablePaginableTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Tests
2 | {
3 | using System.Linq;
4 | using FluentAssertions;
5 | using Xunit;
6 |
7 | public class EnumerableQueryablePaginableTests
8 | {
9 | [Fact]
10 | public void ShouldEqualPageNumber()
11 | {
12 | var source = Enumerable.Range(10, 50);
13 | var expectedPageNumber = 2;
14 |
15 | var sut = source.ToPaginable(expectedPageNumber, itemCountPerPage: 10);
16 |
17 | sut.PageNumber.ShouldBeEquivalentTo(expectedPageNumber);
18 | }
19 |
20 | [Fact]
21 | public void ShouldEqualItemCountPerPage()
22 | {
23 | var source = Enumerable.Range(11, 100);
24 | var expectedItemCountPerPage = 12;
25 |
26 | var sut = source.ToPaginable(2, expectedItemCountPerPage);
27 |
28 | sut.ItemCountPerPage.ShouldBeEquivalentTo(expectedItemCountPerPage);
29 | }
30 |
31 | [Fact]
32 | public void ShouldEqualTotalItemCount()
33 | {
34 | var expectedTotalItemCount = 25;
35 | var source = Enumerable.Range(11, expectedTotalItemCount);
36 |
37 | var sut = source.ToPaginable(2, 10);
38 |
39 | sut.TotalItemCount.ShouldBeEquivalentTo(expectedTotalItemCount);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/EnumerableStaticPaginableTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Tests
2 | {
3 | using System.Linq;
4 | using FluentAssertions;
5 | using Xunit;
6 |
7 | public class EnumerableStaticPaginableTests
8 | {
9 | [Fact]
10 | public void ShouldEqualPageNumber()
11 | {
12 | var source = Enumerable.Range(11, 20);
13 | var expectedPageNumber = 2;
14 |
15 | var sut = source.ToPaginable(expectedPageNumber, 10, 100);
16 |
17 | sut.PageNumber.ShouldBeEquivalentTo(expectedPageNumber);
18 | }
19 |
20 | [Fact]
21 | public void ShouldEqualItemCountPerPage()
22 | {
23 | var source = Enumerable.Range(11, 20);
24 | var expectedItemCountPerPage = 12;
25 |
26 | var sut = source.ToPaginable(2, expectedItemCountPerPage, 100);
27 |
28 | sut.ItemCountPerPage.ShouldBeEquivalentTo(expectedItemCountPerPage);
29 | }
30 |
31 | [Fact]
32 | public void ShouldEqualTotalItemCount()
33 | {
34 | var expectedTotalItemCount = 25;
35 | var source = Enumerable.Range(11, expectedTotalItemCount);
36 |
37 | var sut = source.ToPaginable(2, 10, expectedTotalItemCount);
38 |
39 | sut.TotalItemCount.ShouldBeEquivalentTo(expectedTotalItemCount);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/samples/ConsoleAppDotNet45/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("ConsoleAppDotNet45")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ConsoleAppDotNet45")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("0a23a5a4-8f3f-4d07-a9eb-31aadb95c2e5")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/PaginableCollections/PaginableCollections.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | A light weight pagination framework
5 | Copyright Nicholas Myers
6 | 3.3.0
7 | Nicholas Myers
8 | net45;netstandard1.3;netstandard2.0
9 | PaginableCollections
10 | PaginableCollections
11 | paginable;page;paging;queryable;collections;paginablecollections
12 | https://github.com/neekgreen/PaginableCollections
13 | git
14 | git://github.com/neekgreen/paginable-collections
15 | 3.3.0
16 |
17 |
18 |
19 | bin\
20 | TRACE;DEBUG
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | all
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/PaginableCollections/StaticPaginable.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 |
7 | ///
8 | /// Encapsulates a collection of data.
9 | ///
10 | ///
11 | public class StaticPaginable : Paginable
12 | {
13 | ///
14 | ///
15 | ///
16 | ///
17 | ///
18 | ///
19 | ///
20 | public StaticPaginable(IEnumerable subset, int pageNumber, int itemCountPerPage, int totalItemCount)
21 | {
22 | if (pageNumber < 1)
23 | throw new ArgumentOutOfRangeException(nameof(pageNumber));
24 |
25 | if (itemCountPerPage < 1)
26 | throw new ArgumentOutOfRangeException(nameof(itemCountPerPage));
27 |
28 | var list = subset as IList ?? subset.ToList();
29 | if (list.Count > totalItemCount)
30 | throw new ArgumentOutOfRangeException(nameof(totalItemCount));
31 |
32 | TotalItemCount = totalItemCount;
33 | PageNumber = pageNumber;
34 | ItemCountPerPage = itemCountPerPage;
35 |
36 | innerList.AddRange(list.ToPaginableItemList(pageNumber, itemCountPerPage));
37 |
38 | if (innerList.Any())
39 | {
40 | FirstItemNumber = innerList.First().ItemNumber;
41 | LastItemNumber = innerList.Last().ItemNumber;
42 | }
43 | else
44 | {
45 | FirstItemNumber = 0;
46 | LastItemNumber = 0;
47 | }
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | PaginableCollections
2 | ====================
3 |
4 | [](https://ci.appveyor.com/project/neekgreen/paginablecollections)
5 | [](https://www.nuget.org/packages/paginablecollections)
6 | [](https://www.nuget.org/packages/paginablecollections)
7 | [](https://www.codefactor.io/repository/github/neekgreen/paginablecollections)
8 |
9 | A light weight pagination framework for .NET and .NET Core.
10 |
11 | [](https://img.shields.io/badge/.NET-4.5-blue.svg)
12 | [](https://img.shields.io/badge/.netstandard-1.3-blue.svg)
13 | [](https://img.shields.io/badge/.netstandard-1.3-blue.svg)
14 |
15 | ### Installing PaginableCollections
16 |
17 | You should install [PaginableCollections with NuGet](https://www.nuget.org/packages/paginablecollections):
18 |
19 | Install-Package PaginableCollections
20 |
21 | This command will download and install PaginableCollections. Let me know if you have questions!
22 |
23 |
24 | ## TD;DR
25 |
26 | ```csharp
27 |
28 | var numbers = new int[] { 2, 4, 5, 1, 6, 8, 2, 0, 4, 3, 4, 1, 5, 9, 7, 0, 2, 4, 8, 9 };
29 |
30 | var pageNumber = 2;
31 | var itemCountPerPage = 6;
32 |
33 | var paginable = numbers.ToPaginable(pageNumber, itemCountPerPage);
34 |
35 | foreach(var t in paginable)
36 | {
37 | Console.WriteLine($"{t.ItemNumber}, {t.Item}");
38 | }
39 |
40 | //output
41 | 1, 2
42 | 2, 0
43 | 3, 4
44 | 4, 3
45 | 5, 4
46 | 6, 1
47 |
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/StaticPaginableTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Facts
2 | {
3 | using System.Linq;
4 | using FluentAssertions;
5 | using Xunit;
6 |
7 | public class StaticPaginableFacts
8 | {
9 | [Fact]
10 | public void ShouldEqualPageNumber()
11 | {
12 | var source = Enumerable.Range(11, 20);
13 | var expectedPageNumber = 2;
14 |
15 | IPaginable sut = new StaticPaginable(source, expectedPageNumber, 10, 100);
16 |
17 | sut.PageNumber.ShouldBeEquivalentTo(expectedPageNumber);
18 | }
19 |
20 | [Fact]
21 | public void ShouldEqualItemCountPerPage()
22 | {
23 | var source = Enumerable.Range(11, 20);
24 | var expectedItemCountPerPage = 12;
25 |
26 | var sut = new StaticPaginable(source, 2, expectedItemCountPerPage, 100);
27 |
28 | sut.ItemCountPerPage.ShouldBeEquivalentTo(expectedItemCountPerPage);
29 | }
30 |
31 | [Fact]
32 | public void ShouldEqualTotalItemCount()
33 | {
34 | var expectedTotalItemCount = 25;
35 | var source = Enumerable.Range(11, expectedTotalItemCount);
36 |
37 | var sut = new StaticPaginable(source, 2, 10, expectedTotalItemCount);
38 |
39 | sut.TotalItemCount.ShouldBeEquivalentTo(expectedTotalItemCount);
40 | }
41 |
42 | [Fact]
43 | public void ShouldEqualFirstElementNextPage()
44 | {
45 | var source = Enumerable.Range(1, 100);
46 | var paginable = new StaticPaginable(source, 3, 10, 100);
47 |
48 | var sut = paginable.ElementAt(0);
49 |
50 | sut.ItemNumber.ShouldBeEquivalentTo(21);
51 | sut.Item.ShouldBeEquivalentTo(1);
52 | sut.PageNumber.ShouldBeEquivalentTo(3);
53 | sut.ItemCountPerPage.ShouldBeEquivalentTo(10);
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/QueryablePaginableTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Facts
2 | {
3 | using System.Linq;
4 | using FluentAssertions;
5 | using Xunit;
6 |
7 | public class QueryablePaginableFacts
8 | {
9 | [Fact]
10 | public void ShouldEqualPageNumber()
11 | {
12 | var source = Enumerable.Range(10, 50).AsQueryable();
13 | var expectedPageNumber = 2;
14 |
15 | var sut = new QueryableBasedPaginable(source, expectedPageNumber, 10);
16 |
17 | sut.PageNumber.ShouldBeEquivalentTo(expectedPageNumber);
18 | }
19 |
20 | [Fact]
21 | public void ShouldEqualItemCountPerPage()
22 | {
23 | var source = Enumerable.Range(11, 100).AsQueryable();
24 | var expectedItemCountPerPage = 12;
25 |
26 | var sut = new QueryableBasedPaginable(source, 2, expectedItemCountPerPage);
27 |
28 | sut.ItemCountPerPage.ShouldBeEquivalentTo(expectedItemCountPerPage);
29 | }
30 |
31 | [Fact]
32 | public void ShouldEqualTotalItemCount()
33 | {
34 | var expectedTotalItemCount = 25;
35 | var source = Enumerable.Range(11, expectedTotalItemCount).AsQueryable();
36 |
37 | var sut = new QueryableBasedPaginable(source, 2, 10);
38 |
39 | sut.TotalItemCount.ShouldBeEquivalentTo(expectedTotalItemCount);
40 | }
41 |
42 | [Fact]
43 | public void ShouldEqualFirstElementNextPage()
44 | {
45 | var source = Enumerable.Range(1, 100).AsQueryable();
46 | var paginable = new QueryableBasedPaginable(source, 3, 10);
47 |
48 | var sut = paginable.ElementAt(0);
49 |
50 | sut.ItemNumber.ShouldBeEquivalentTo(21);
51 | sut.Item.ShouldBeEquivalentTo(21);
52 | sut.PageNumber.ShouldBeEquivalentTo(3);
53 | sut.ItemCountPerPage.ShouldBeEquivalentTo(10);
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/tests/PaginableCollections.Tests/PagerItemTests.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections.Facts
2 | {
3 | using FluentAssertions;
4 | using Xunit;
5 |
6 | public class StaticPagerPageFacts
7 | {
8 | [Fact]
9 | public void ShouldSetPageNumber()
10 | {
11 | var pageNumber = 1;
12 | var sut = new PagerItem(pageNumber, 10);
13 |
14 | sut.PageNumber.ShouldBeEquivalentTo(pageNumber);
15 | }
16 |
17 | [Fact]
18 | public void ShouldSetIsFirstPage()
19 | {
20 | var pageNumber = 1;
21 | var sut = new PagerItem(pageNumber, 10);
22 |
23 | sut.IsFirstPage.ShouldBeEquivalentTo(true);
24 | }
25 |
26 | [Fact]
27 | public void ShouldSetIsPreviousPage()
28 | {
29 | var pageNumber = 1;
30 | var sut = new PagerItem(pageNumber, 10);
31 |
32 | sut.HasPreviousPage.ShouldBeEquivalentTo(false);
33 | }
34 |
35 | [Fact]
36 | public void ShouldSetHasNextPage()
37 | {
38 | var pageNumber = 1;
39 | var sut = new PagerItem(pageNumber, 10);
40 |
41 | sut.HasNextPage.ShouldBeEquivalentTo(true);
42 | }
43 |
44 | [Fact]
45 | public void ShouldSetTotalPageCount()
46 | {
47 | var totalPageCount = 1;
48 | var sut = new PagerItem(1, totalPageCount);
49 |
50 | sut.TotalPageCount.ShouldBeEquivalentTo(totalPageCount);
51 | }
52 |
53 | [Fact]
54 | public void ShouldBeLastPage()
55 | {
56 | var totalPageCount = 10;
57 | var sut = new PagerItem(totalPageCount, totalPageCount);
58 |
59 | sut.IsLastPage.ShouldBeEquivalentTo(true);
60 | }
61 |
62 | [Fact]
63 | public void ShouldBeHasNextPage()
64 | {
65 | var totalPageCount = 10;
66 | var sut = new PagerItem(totalPageCount, totalPageCount);
67 |
68 | sut.HasNextPage.ShouldBeEquivalentTo(false);
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/PaginableCollections/StaticPager.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | using System.Collections.Generic;
4 |
5 | public class StaticPager : IPager
6 | {
7 | private readonly IList pages;
8 |
9 | public StaticPager(IPaginable paginable, int maximumPageNumberCount)
10 | {
11 | MaximumPageNumberCount = maximumPageNumberCount;
12 | TotalPageCount = paginable.TotalPageCount;
13 |
14 | var firstPageToDisplay = 1;
15 | var lastPageToDisplay = paginable.TotalPageCount;
16 | var pageNumbersToDisplay = lastPageToDisplay;
17 |
18 | if (paginable.TotalPageCount > maximumPageNumberCount)
19 | {
20 | var maxPageNumbersToDisplay = maximumPageNumberCount;
21 | firstPageToDisplay = paginable.PageNumber - (maxPageNumbersToDisplay / 2);
22 | if (firstPageToDisplay < 1)
23 | {
24 | firstPageToDisplay = 1;
25 | }
26 | pageNumbersToDisplay = maxPageNumbersToDisplay;
27 | lastPageToDisplay = firstPageToDisplay + pageNumbersToDisplay - 1;
28 | if (lastPageToDisplay > paginable.TotalPageCount)
29 | {
30 | firstPageToDisplay = paginable.TotalPageCount - maxPageNumbersToDisplay + 1;
31 | }
32 | }
33 |
34 | var totalPageNumber = paginable.TotalPageCount;
35 | if (totalPageNumber == 0)
36 | {
37 | totalPageNumber = 1;
38 | }
39 |
40 | pages = new List();
41 |
42 | for (int i = firstPageToDisplay; i <= firstPageToDisplay + pageNumbersToDisplay - 1; i++)
43 | {
44 | pages.Add(new PagerItem(i, totalPageNumber));
45 | }
46 | }
47 |
48 | IEnumerable IPager.GetPages()
49 | {
50 | return pages;
51 | }
52 |
53 | public int TotalPageCount { get; private set; }
54 | public int MaximumPageNumberCount { get; private set; }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/PaginableCollections/QueryableBasedPaginable.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 |
7 | ///
8 | /// This paginable that uses the underlying data source to calculate pagination statistics.
9 | ///
10 | ///
11 | public class QueryableBasedPaginable : Paginable
12 | {
13 | ///
14 | ///
15 | ///
16 | ///
17 | ///
18 | ///
19 | public QueryableBasedPaginable(IQueryable queryable, int pageNumber, int itemCountPerPage)
20 | {
21 | if (pageNumber < 1)
22 | throw new ArgumentOutOfRangeException(nameof(pageNumber));
23 |
24 | if (itemCountPerPage < 1)
25 | throw new ArgumentOutOfRangeException(nameof(itemCountPerPage));
26 |
27 | TotalItemCount = queryable?.Count() ?? 0;
28 | PageNumber = pageNumber;
29 | ItemCountPerPage = itemCountPerPage;
30 |
31 | if (TotalItemCount > 0)
32 | {
33 | innerList.AddRange(queryable
34 | .Skip((pageNumber - 1) * ItemCountPerPage)
35 | .Take(ItemCountPerPage)
36 | .ToPaginableItemList(pageNumber, itemCountPerPage));
37 | }
38 |
39 | if (innerList.Any())
40 | {
41 | FirstItemNumber = innerList.First().ItemNumber;
42 | LastItemNumber = innerList.Last().ItemNumber;
43 | }
44 | else
45 | {
46 | FirstItemNumber = 0;
47 | LastItemNumber = 0;
48 | }
49 | }
50 |
51 | ///
52 | ///
53 | ///
54 | ///
55 | ///
56 | ///
57 | public QueryableBasedPaginable(IEnumerable superset, int pageNumber, int itemCountPerPage)
58 | : this(superset.AsQueryable(), pageNumber, itemCountPerPage) { }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/PaginableCollections/IPaginable.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | using System.Collections;
4 | using System.Collections.Generic;
5 |
6 | ///
7 | /// Non-generic contract representing a page of data.
8 | ///
9 | public interface IPaginable : IEnumerable
10 | {
11 | ///
12 | /// Total number of pages.
13 | ///
14 | int TotalPageCount { get; }
15 |
16 | ///
17 | /// Total item count.
18 | ///
19 | int TotalItemCount { get; }
20 |
21 | ///
22 | /// Current page number.
23 | ///
24 | int PageNumber { get; }
25 |
26 | ///
27 | /// Requested item count per page.
28 | ///
29 | int ItemCountPerPage { get; }
30 |
31 | ///
32 | /// Identifies the first page.
33 | ///
34 | bool IsFirstPage { get; }
35 |
36 | ///
37 | /// Identifies the last page.
38 | ///
39 | bool IsLastPage { get; }
40 |
41 | ///
42 | /// Identifies if there is a previous page.
43 | ///
44 | bool HasPreviousPage { get; }
45 |
46 | ///
47 | /// Identifies if there is a next page.
48 | ///
49 | bool HasNextPage { get; }
50 |
51 | ///
52 | /// The first item number of the page.
53 | ///
54 | int FirstItemNumber { get; }
55 |
56 | ///
57 | /// The last item number of this page.
58 | ///
59 | int LastItemNumber { get; }
60 | }
61 |
62 | ///
63 | /// Generic contract representing a page of data.
64 | ///
65 | ///
66 | public interface IPaginable : IEnumerable>, IPaginable
67 | {
68 | ///
69 | ///
70 | ///
71 | ///
72 | ///
73 | IPaginableItem this[int index] { get; }
74 |
75 | ///
76 | /// Number of items in this paginable.
77 | ///
78 | int Count { get; }
79 | }
80 | }
--------------------------------------------------------------------------------
/src/PaginableCollections/PaginableExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | using System.Collections.Generic;
4 | using System.Linq;
5 |
6 | public static class PaginableExtensions
7 | {
8 | ///
9 | /// Convert queryable to paginable.
10 | ///
11 | ///
12 | ///
13 | ///
14 | ///
15 | ///
16 | public static IPaginable ToPaginable(this IQueryable queryable, int pageNumber, int itemCountPerPage)
17 | {
18 | return new QueryableBasedPaginable(queryable, pageNumber, itemCountPerPage);
19 | }
20 |
21 | ///
22 | /// Convert queryable to paginable.
23 | ///
24 | ///
25 | ///
26 | ///
27 | ///
28 | public static IPaginable ToPaginable(this IQueryable queryable, IPaginableRequest paginableRequest)
29 | {
30 | return queryable.ToPaginable(paginableRequest.PageNumber, paginableRequest.ItemCountPerPage);
31 | }
32 |
33 | ///
34 | ///
35 | ///
36 | ///
37 | ///
38 | ///
39 | public static IPager ToPager(this IPaginable paginable, int maximumPageNumberCount)
40 | {
41 | return new StaticPager(paginable, maximumPageNumberCount);
42 | }
43 |
44 | ///
45 | ///
46 | ///
47 | ///
48 | ///
49 | ///
50 | ///
51 | ///
52 | internal static IEnumerable> ToPaginableItemList(this IEnumerable t, int pageNumber, int itemCountPerPage)
53 | {
54 | var offset = (pageNumber - 1) * itemCountPerPage;
55 | var list = t as IList ?? t.ToList();
56 | for (var i = 0; i < list.Count; i++)
57 | {
58 | yield return new PaginableItem(list[i], offset + 1, pageNumber, itemCountPerPage);
59 | offset++;
60 | }
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/samples/ConsoleAppDotNet45/ConsoleAppDotNet45.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {0A23A5A4-8F3F-4D07-A9EB-31AADB95C2E5}
8 | Exe
9 | ConsoleAppDotNet45
10 | ConsoleAppDotNet45
11 | v4.5
12 | 512
13 |
14 |
15 | AnyCPU
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | AnyCPU
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | {8f6c7555-710f-443f-a5ca-bf50fc37484d}
53 | PaginableCollections
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at neekgreen@users.noreply.github.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/src/PaginableCollections/Paginable.cs:
--------------------------------------------------------------------------------
1 | namespace PaginableCollections
2 | {
3 | using System;
4 | using System.Collections;
5 | using System.Collections.Generic;
6 |
7 | ///
8 | /// Base class represents page of items.
9 | ///
10 | /// The type of items in this paginable.
11 | public abstract class Paginable : IPaginable
12 | {
13 | protected readonly List> innerList = new List>();
14 |
15 | ///
16 | ///
17 | ///
18 | ///
19 | IEnumerator IEnumerable.GetEnumerator()
20 | {
21 | return innerList.GetEnumerator();
22 | }
23 |
24 | IEnumerator> IEnumerable>.GetEnumerator()
25 | {
26 | return innerList.GetEnumerator();
27 | }
28 |
29 | ///
30 | /// Total number of items.
31 | ///
32 | public int TotalItemCount { get; protected set; }
33 |
34 | ///
35 | /// Requested page number.
36 | ///
37 | public int PageNumber { get; protected set; }
38 |
39 | ///
40 | /// Requested number of items per page.
41 | ///
42 | public int ItemCountPerPage { get; protected set; }
43 |
44 | ///
45 | ///
46 | ///
47 | ///
48 | ///
49 | IPaginableItem IPaginable.this[int index] => innerList[index];
50 |
51 | ///
52 | /// Number of items in this result set.
53 | ///
54 | public int Count => innerList.Count;
55 |
56 | ///
57 | /// Total number of pages.
58 | ///
59 | public int TotalPageCount =>
60 | TotalItemCount > 0 ? (int)Math.Ceiling(TotalItemCount / (double)ItemCountPerPage) : 0;
61 |
62 | ///
63 | /// Identifies the first page.
64 | ///
65 | public bool IsFirstPage => PageNumber == 1;
66 |
67 | ///
68 | /// Identifies the last page.
69 | ///
70 | public bool IsLastPage => PageNumber >= TotalPageCount;
71 |
72 | ///
73 | /// Identifies if a previous page is available.
74 | ///
75 | public bool HasPreviousPage => PageNumber > 1;
76 |
77 | ///
78 | /// Identifies if a next page is available.
79 | ///
80 | public bool HasNextPage => PageNumber < TotalPageCount;
81 |
82 | ///
83 | /// Identifies the first item number of the page.
84 | ///
85 | public int FirstItemNumber { get; protected set; }
86 |
87 | ///
88 | /// Identifies the last item number of the page.
89 | ///
90 | public int LastItemNumber { get; protected set; }
91 | }
92 |
93 |
94 | ///
95 | ///
96 | ///
97 | public static class Paginable
98 | {
99 | ///
100 | /// Returns new empty paginable collection.
101 | ///
102 | ///
103 | public static IPaginable Empty()
104 | {
105 | return new EmptyPaginable();
106 | }
107 | }
108 | }
--------------------------------------------------------------------------------
/PaginableCollections.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26730.3
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{B15992BA-EB0A-4096-BA64-A7E1B7F6FA32}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{50BAA0E6-841D-4678-9679-38A2A3456F60}"
9 | ProjectSection(SolutionItems) = preProject
10 | appveyor.yml = appveyor.yml
11 | build.cake = build.cake
12 | EndProjectSection
13 | EndProject
14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PaginableCollections", "src\PaginableCollections\PaginableCollections.csproj", "{8F6C7555-710F-443F-A5CA-BF50FC37484D}"
15 | EndProject
16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PaginableCollections.Tests", "tests\PaginableCollections.Tests\PaginableCollections.Tests.csproj", "{1834508B-44C8-44AD-83F2-19ACEE028AAF}"
17 | EndProject
18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppDotNet45", "samples\ConsoleAppDotNet45\ConsoleAppDotNet45.csproj", "{0A23A5A4-8F3F-4D07-A9EB-31AADB95C2E5}"
19 | EndProject
20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{FC4DDD23-0F50-4F65-AA6D-DB5D2657C4D3}"
21 | EndProject
22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleAppDotNetCore20", "samples\ConsoleAppDotNetCore20\ConsoleAppDotNetCore20.csproj", "{AF24831C-3E29-4CA4-A209-DD97C5203E5F}"
23 | EndProject
24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleAppDotNetCore11", "samples\ConsoleAppDotNetCore11\ConsoleAppDotNetCore11.csproj", "{48954628-76B2-4736-95F3-D2F508330893}"
25 | EndProject
26 | Global
27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
28 | Debug|Any CPU = Debug|Any CPU
29 | Release|Any CPU = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
32 | {8F6C7555-710F-443F-A5CA-BF50FC37484D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {8F6C7555-710F-443F-A5CA-BF50FC37484D}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {8F6C7555-710F-443F-A5CA-BF50FC37484D}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {8F6C7555-710F-443F-A5CA-BF50FC37484D}.Release|Any CPU.Build.0 = Release|Any CPU
36 | {1834508B-44C8-44AD-83F2-19ACEE028AAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 | {1834508B-44C8-44AD-83F2-19ACEE028AAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 | {1834508B-44C8-44AD-83F2-19ACEE028AAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {1834508B-44C8-44AD-83F2-19ACEE028AAF}.Release|Any CPU.Build.0 = Release|Any CPU
40 | {0A23A5A4-8F3F-4D07-A9EB-31AADB95C2E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41 | {0A23A5A4-8F3F-4D07-A9EB-31AADB95C2E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
42 | {0A23A5A4-8F3F-4D07-A9EB-31AADB95C2E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 | {0A23A5A4-8F3F-4D07-A9EB-31AADB95C2E5}.Release|Any CPU.Build.0 = Release|Any CPU
44 | {AF24831C-3E29-4CA4-A209-DD97C5203E5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45 | {AF24831C-3E29-4CA4-A209-DD97C5203E5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
46 | {AF24831C-3E29-4CA4-A209-DD97C5203E5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
47 | {AF24831C-3E29-4CA4-A209-DD97C5203E5F}.Release|Any CPU.Build.0 = Release|Any CPU
48 | {48954628-76B2-4736-95F3-D2F508330893}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49 | {48954628-76B2-4736-95F3-D2F508330893}.Debug|Any CPU.Build.0 = Debug|Any CPU
50 | {48954628-76B2-4736-95F3-D2F508330893}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 | {48954628-76B2-4736-95F3-D2F508330893}.Release|Any CPU.Build.0 = Release|Any CPU
52 | EndGlobalSection
53 | GlobalSection(SolutionProperties) = preSolution
54 | HideSolutionNode = FALSE
55 | EndGlobalSection
56 | GlobalSection(NestedProjects) = preSolution
57 | {1834508B-44C8-44AD-83F2-19ACEE028AAF} = {B15992BA-EB0A-4096-BA64-A7E1B7F6FA32}
58 | {0A23A5A4-8F3F-4D07-A9EB-31AADB95C2E5} = {FC4DDD23-0F50-4F65-AA6D-DB5D2657C4D3}
59 | {AF24831C-3E29-4CA4-A209-DD97C5203E5F} = {FC4DDD23-0F50-4F65-AA6D-DB5D2657C4D3}
60 | {48954628-76B2-4736-95F3-D2F508330893} = {FC4DDD23-0F50-4F65-AA6D-DB5D2657C4D3}
61 | EndGlobalSection
62 | GlobalSection(ExtensibilityGlobals) = postSolution
63 | SolutionGuid = {BF46CCCA-4A7A-42C2-BB58-2A5A43DBFC87}
64 | EndGlobalSection
65 | EndGlobal
66 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | build/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opensdf
80 | *.sdf
81 | *.cachefile
82 |
83 | # Visual Studio profiler
84 | *.psess
85 | *.vsp
86 | *.vspx
87 | *.sap
88 |
89 | # TFS 2012 Local Workspace
90 | $tf/
91 |
92 | # Guidance Automation Toolkit
93 | *.gpState
94 |
95 | # ReSharper is a .NET coding add-in
96 | _ReSharper*/
97 | *.[Rr]e[Ss]harper
98 | *.DotSettings.user
99 |
100 | # JustCode is a .NET coding add-in
101 | .JustCode
102 |
103 | # TeamCity is a build add-in
104 | _TeamCity*
105 |
106 | # DotCover is a Code Coverage Tool
107 | *.dotCover
108 |
109 | # NCrunch
110 | _NCrunch_*
111 | .*crunch*.local.xml
112 | nCrunchTemp_*
113 |
114 | # MightyMoose
115 | *.mm.*
116 | AutoTest.Net/
117 |
118 | # Web workbench (sass)
119 | .sass-cache/
120 |
121 | # Installshield output folder
122 | [Ee]xpress/
123 |
124 | # DocProject is a documentation generator add-in
125 | DocProject/buildhelp/
126 | DocProject/Help/*.HxT
127 | DocProject/Help/*.HxC
128 | DocProject/Help/*.hhc
129 | DocProject/Help/*.hhk
130 | DocProject/Help/*.hhp
131 | DocProject/Help/Html2
132 | DocProject/Help/html
133 |
134 | # Click-Once directory
135 | publish/
136 |
137 | # Publish Web Output
138 | *.[Pp]ublish.xml
139 | *.azurePubxml
140 | # TODO: Comment the next line if you want to checkin your web deploy settings
141 | # but database connection strings (with potential passwords) will be unencrypted
142 | *.pubxml
143 | *.publishproj
144 |
145 | # NuGet Packages
146 | *.nupkg
147 | # The packages folder can be ignored because of Package Restore
148 | **/packages/*
149 | # except build/, which is used as an MSBuild target.
150 | !**/packages/build/
151 | # Uncomment if necessary however generally it will be regenerated when needed
152 | #!**/packages/repositories.config
153 |
154 | # Windows Azure Build Output
155 | csx/
156 | *.build.csdef
157 |
158 | # Windows Azure Emulator
159 | ecf/
160 | rcf/
161 |
162 | # Windows Store app package directory
163 | AppPackages/
164 |
165 | # Visual Studio cache files
166 | # files ending in .cache can be ignored
167 | *.[Cc]ache
168 | # but keep track of directories ending in .cache
169 | !*.[Cc]ache/
170 |
171 | # Others
172 | ClientBin/
173 | [Ss]tyle[Cc]op.*
174 | ~$*
175 | *~
176 | *.dbmdl
177 | *.dbproj.schemaview
178 | *.pfx
179 | *.publishsettings
180 | node_modules/
181 | orleans.codegen.cs
182 |
183 | # RIA/Silverlight projects
184 | Generated_Code/
185 |
186 | # Backup & report files from converting an old project file
187 | # to a newer Visual Studio version. Backup files are not needed,
188 | # because we have git ;-)
189 | _UpgradeReport_Files/
190 | Backup*/
191 | UpgradeLog*.XML
192 | UpgradeLog*.htm
193 |
194 | # SQL Server files
195 | *.mdf
196 | *.ldf
197 |
198 | # Business Intelligence projects
199 | *.rdl.data
200 | *.bim.layout
201 | *.bim_*.settings
202 |
203 | # Microsoft Fakes
204 | FakesAssemblies/
205 |
206 | # GhostDoc plugin setting file
207 | *.GhostDoc.xml
208 |
209 | # Node.js Tools for Visual Studio
210 | .ntvs_analysis.dat
211 |
212 | # Visual Studio 6 build log
213 | *.plg
214 |
215 | # Visual Studio 6 workspace options file
216 | *.opt
217 |
218 | # Visual Studio LightSwitch build output
219 | **/*.HTMLClient/GeneratedArtifacts
220 | **/*.DesktopClient/GeneratedArtifacts
221 | **/*.DesktopClient/ModelManifest.xml
222 | **/*.Server/GeneratedArtifacts
223 | **/*.Server/ModelManifest.xml
224 | _Pvt_Extensions
225 |
226 | # Paket dependency manager
227 | .paket/paket.exe
228 |
229 | # FAKE - F# Make
230 | .fake/
231 |
232 | # VSCode
233 | .dotnet/
234 |
235 | tools/*
236 | !tools/packages.config
--------------------------------------------------------------------------------