From 485ae7cfc0d761f806c3fca97283a02920c2f079 Mon Sep 17 00:00:00 2001 From: rikolearn Date: Mon, 24 Apr 2023 13:51:18 +0330 Subject: [PATCH 1/6] add pagination for repository and response message --- ....Commons.PresentationInfrastructure.csproj | 1 + .../Converters/JsonForceDefaultConverter.cs | 19 ++++++++++ .../Responses/GenericResponseBase.cs | 9 +++++ .../GenericResponseBaseWithPagination.cs | 7 ++++ .../Responses/PaginationMetadata.cs | 13 +++++++ .../Responses/Response.cs | 19 ++++++++++ .../BSN.Commons/Dto/PagedEntityCollection.cs | 36 +++++++++++++++++++ .../Extensions/IQueryableExtensions.cs | 30 ++++++++++++++++ 8 files changed, 134 insertions(+) create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Responses/Response.cs create mode 100644 Source/BSN.Commons/Dto/PagedEntityCollection.cs create mode 100644 Source/BSN.Commons/Extensions/IQueryableExtensions.cs diff --git a/Source/BSN.Commons.PresentationInfrastructure/BSN.Commons.PresentationInfrastructure.csproj b/Source/BSN.Commons.PresentationInfrastructure/BSN.Commons.PresentationInfrastructure.csproj index eccb3bc..dda0e7f 100644 --- a/Source/BSN.Commons.PresentationInfrastructure/BSN.Commons.PresentationInfrastructure.csproj +++ b/Source/BSN.Commons.PresentationInfrastructure/BSN.Commons.PresentationInfrastructure.csproj @@ -17,6 +17,7 @@ + diff --git a/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs new file mode 100644 index 0000000..302035e --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs @@ -0,0 +1,19 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace BSN.Commons.Converters +{ + public class JsonForceDefaultConverter : JsonConverter + { + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(ref reader); + } + + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value); + } + } +} diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs new file mode 100644 index 0000000..fc92f1a --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs @@ -0,0 +1,9 @@ +namespace BSN.Commons.Responses +{ + public class GenericResponseBase : Response where T : class + { + public T Data { get; set; } + + public GenericResponseBase() { } + } +} diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs new file mode 100644 index 0000000..94bce8d --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs @@ -0,0 +1,7 @@ +namespace BSN.Commons.Responses +{ + public class GenericResponseBaseWithPagination : GenericResponseBase where T : class + { + public PaginationMetadata Meta { get; set; } + } +} diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs new file mode 100644 index 0000000..1cfd739 --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs @@ -0,0 +1,13 @@ +namespace BSN.Commons.Responses +{ + public class PaginationMetadata + { + public uint Page { get; set; } + + public uint PageCount { get; set; } + + public uint PageSize { get; set; } + + public uint RecordCount { get; set; } + } +} diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/Response.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/Response.cs new file mode 100644 index 0000000..3524f93 --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/Response.cs @@ -0,0 +1,19 @@ +using BSN.Commons.Converters; +using BSN.Commons.PresentationInfrastructure; +using System.Text.Json.Serialization; + +namespace BSN.Commons.Responses +{ + /// + /// During serialization and deserialization operations, enumeration values are always converted to and from strings. + /// This is possible through registering the 'JsonStringEnumConverter' in our DI infrastructure. There is once exception, + /// namely the 'StatusCode' property of the 'ResponseBase' class which should keep it's default numeral value when being converted. + /// + public class Response : ResponseBase + { + public new bool IsSuccess => (int)StatusCode >= 200 && (int)StatusCode <= 299; + + [JsonConverter(typeof(JsonForceDefaultConverter))] + public new ResponseStatusCode StatusCode { get; set; } + } +} diff --git a/Source/BSN.Commons/Dto/PagedEntityCollection.cs b/Source/BSN.Commons/Dto/PagedEntityCollection.cs new file mode 100644 index 0000000..5b3c28c --- /dev/null +++ b/Source/BSN.Commons/Dto/PagedEntityCollection.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; + +namespace BSN.Commons.Dto +{ + /// + /// Stores the paginated data for the given entity type. + /// + /// Type of Entity for which pagination is being implemented. + public class PagedEntityCollection + { + /// + /// Current page number + /// + public uint CurrentPage { get; set; } + + /// + /// Total number of pages + /// + public uint PageCount { get; set; } + + /// + /// Number of records per page + /// + public uint PageSize { get; set; } + + /// + /// Total number of records that exist for the query + /// + public uint RecordCount { get; set; } + + /// + /// IEnumerable of the paginated data + /// + public IEnumerable Results { get; set; } + } +} diff --git a/Source/BSN.Commons/Extensions/IQueryableExtensions.cs b/Source/BSN.Commons/Extensions/IQueryableExtensions.cs new file mode 100644 index 0000000..b1bf084 --- /dev/null +++ b/Source/BSN.Commons/Extensions/IQueryableExtensions.cs @@ -0,0 +1,30 @@ +using BSN.Commons.Dto; +using System; +using System.Linq; + +namespace BSN.Commons.Extensions +{ + public static partial class IQueryableExtensions + { + public static PagedEntityCollection Paginate(this IQueryable query, uint pageNumber, uint pageSize) + { + if (pageNumber == 0) + throw new ArgumentException("Must be greater than zero.", nameof(pageNumber)); + + if (pageSize == 0) + throw new ArgumentException("Must be greater than zero.", nameof(pageSize)); + + var result = new PagedEntityCollection + { + CurrentPage = pageNumber, + PageSize = pageSize, + RecordCount = (uint)query.Count(), + Results = query.Skip((int)((pageNumber - 1) * pageSize)).Take((int)pageSize).ToList() + }; + + result.PageCount = (uint)Math.Ceiling((double)result.RecordCount / pageSize); + + return result; + } + } +} From 50b56fd5cbd2644bb855727405863575cb06bc28 Mon Sep 17 00:00:00 2001 From: rikolearn Date: Mon, 24 Apr 2023 17:01:43 +0330 Subject: [PATCH 2/6] add some comments --- .../Responses/PaginationMetadata.cs | 15 +++++++++++++++ .../Extensions/IQueryableExtensions.cs | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs index 1cfd739..f57abdc 100644 --- a/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs @@ -1,13 +1,28 @@ namespace BSN.Commons.Responses { + /// + /// Stores the paginated meta data. + /// public class PaginationMetadata { + /// + /// Current page number + /// public uint Page { get; set; } + /// + /// Total number of pages + /// public uint PageCount { get; set; } + /// + /// Number of records per page + /// public uint PageSize { get; set; } + /// + /// Total number of records that exist + /// public uint RecordCount { get; set; } } } diff --git a/Source/BSN.Commons/Extensions/IQueryableExtensions.cs b/Source/BSN.Commons/Extensions/IQueryableExtensions.cs index b1bf084..68925fa 100644 --- a/Source/BSN.Commons/Extensions/IQueryableExtensions.cs +++ b/Source/BSN.Commons/Extensions/IQueryableExtensions.cs @@ -6,6 +6,10 @@ namespace BSN.Commons.Extensions { public static partial class IQueryableExtensions { + /// + /// Paginate IQueryable of + /// with given pageNumber and pageSize + /// public static PagedEntityCollection Paginate(this IQueryable query, uint pageNumber, uint pageSize) { if (pageNumber == 0) From 8ae39ad93660120983e6788a563000816d9fe13a Mon Sep 17 00:00:00 2001 From: rikolearn Date: Tue, 25 Apr 2023 13:59:48 +0330 Subject: [PATCH 3/6] add needed comments for pr --- .../Converters/JsonForceDefaultConverter.cs | 4 ++++ .../Responses/GenericResponseBase.cs | 8 ++++++-- .../Responses/GenericResponseBaseWithPagination.cs | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs index 302035e..89c08d8 100644 --- a/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs +++ b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs @@ -4,6 +4,10 @@ namespace BSN.Commons.Converters { + /// + /// Force to convert an object or value to or from JSON in default form. + /// + /// The type of object or value handled by the converter. public class JsonForceDefaultConverter : JsonConverter { public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs index fc92f1a..5710686 100644 --- a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs @@ -1,9 +1,13 @@ namespace BSN.Commons.Responses { + /// + /// Add data as given type to response class. + /// + /// The type of object or value handled by the class. public class GenericResponseBase : Response where T : class { - public T Data { get; set; } - public GenericResponseBase() { } + + public T Data { get; set; } } } diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs index 94bce8d..1a35062 100644 --- a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs @@ -1,5 +1,9 @@ namespace BSN.Commons.Responses { + /// + /// Add pagination meta data for given type to response class. + /// + /// The type of object or value handled by the class. public class GenericResponseBaseWithPagination : GenericResponseBase where T : class { public PaginationMetadata Meta { get; set; } From 28087eb9bf77289a48b773ff58994b0e223857a5 Mon Sep 17 00:00:00 2001 From: rikolearn Date: Wed, 26 Apr 2023 00:32:28 +0330 Subject: [PATCH 4/6] fix PR commen --- .../Converters/JsonForceDefaultConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs index 89c08d8..ec698ff 100644 --- a/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs +++ b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs @@ -5,7 +5,7 @@ namespace BSN.Commons.Converters { /// - /// Force to convert an object or value to or from JSON in default form. + /// Force to keep numeral object or value, while convert an object or value to or from JSON. /// /// The type of object or value handled by the converter. public class JsonForceDefaultConverter : JsonConverter From 65288f935d6a35708eeb90a881e0c0a79479ece5 Mon Sep 17 00:00:00 2001 From: rikolearn Date: Wed, 26 Apr 2023 10:43:07 +0330 Subject: [PATCH 5/6] fix PR comments --- .../Responses/GenericResponseBaseWithPagination.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs index 1a35062..80edcb1 100644 --- a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs @@ -1,11 +1,17 @@ namespace BSN.Commons.Responses { /// - /// Add pagination meta data for given type to response class. + /// Generic response base for paginated data. /// - /// The type of object or value handled by the class. + /// + /// Paginated response provides metadata for navigation purpose. + /// + /// Data type. public class GenericResponseBaseWithPagination : GenericResponseBase where T : class { + /// + /// Pagination metada used by the client as the parameters for navigation through whole records. + /// public PaginationMetadata Meta { get; set; } } } From 1f54211dff632457fec0b76ba4483ed2fd47bd41 Mon Sep 17 00:00:00 2001 From: rikolearn Date: Wed, 26 Apr 2023 13:40:30 +0330 Subject: [PATCH 6/6] fix pr comment --- .../Converters/JsonForceDefaultConverter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs index ec698ff..a333444 100644 --- a/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs +++ b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs @@ -6,6 +6,7 @@ namespace BSN.Commons.Converters { /// /// Force to keep numeral object or value, while convert an object or value to or from JSON. + /// for example 'StatusCode' in Response that should stay numeral. /// /// The type of object or value handled by the converter. public class JsonForceDefaultConverter : JsonConverter