Notify.NotificationPattern.Library 1.0.5

dotnet add package Notify.NotificationPattern.Library --version 1.0.5
                    
NuGet\Install-Package Notify.NotificationPattern.Library -Version 1.0.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Notify.NotificationPattern.Library" Version="1.0.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Notify.NotificationPattern.Library" Version="1.0.5" />
                    
Directory.Packages.props
<PackageReference Include="Notify.NotificationPattern.Library" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Notify.NotificationPattern.Library --version 1.0.5
                    
#r "nuget: Notify.NotificationPattern.Library, 1.0.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Notify.NotificationPattern.Library@1.0.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Notify.NotificationPattern.Library&version=1.0.5
                    
Install as a Cake Addin
#tool nuget:?package=Notify.NotificationPattern.Library&version=1.0.5
                    
Install as a Cake Tool

GitHub last commit (by committer) GitHub License GitHub repo size

Notifiy

Available in: pt-br

Welcome to Notify, your friendly and easy alternative for implementing and using the Notification Pattern in WebApi projects in C# with the NET6.0 framework. If you're looking for a simple and effective way to handle validation messages, errors and notifications, Notify is an option.

Features

  • Domain notifications
  • Global Scope Filter for response handling

Prerequisites

To use the library, you must have the Dot Net6.0 SDK version installed in your environment.

Usage:

Service Registration (Program.cs)

builder.Services.AddScoped<INotifiableContext, NotifiableContext>();
builder.Services.RegisterNotificationMessagesService(MovieCreateNotifications.Notifications);
 

Suggestion

To register the set of notifications when calling the method RegisterNotificationMessagesService, you can use a class with static properties to store your notifications and their respective identification codes, for more user-friendly reading.

Notification Codes

    public static class NotificationCode
    {
        public const long MovieNotFound = 1;
        public const long InvalidMovieIdentifier = 2;
        public const long TitleCantBeNullOrEmpty = 3;
    }

Notifications

public static class MovieCreateNotifications
    {
        public static readonly Dictionary<long, NotificationParameters> Notifications = new()
        {
            {
                NotificationCode.MovieNotFound,
                new NotificationParameters(
                    "Filme não encontrado na base de dados",
                    nameof(MovieCreateRequest.Id),
                    HttpStatusCode.UnprocessableEntity,
                    NotificationSeverity.Warning)
            },
            {
                NotificationCode.CantRemoveUnregisteredMovie,
                new NotificationParameters(
                    "Não é possível remover um filme não cadastrado",
                    nameof(MovieCreateRequest.Id),
                    HttpStatusCode.UnprocessableEntity,
                    NotificationSeverity.Warning)
            },
            {
                NotificationCode.InvalidMovieIdentifier,
                new NotificationParameters(
                    "Identificador informado não é válido",
                    nameof(MovieCreateRequest.Id),
                    HttpStatusCode.UnprocessableEntity,
                    NotificationSeverity.Warning)
            }
        };
    }

Filter application in Controllers

Gloabal Scope

builder.Services.AddControllers(o =>
{
    o.Filters.Add<NotifiableFilter>();
});

By Controller

    [NotifiableFilter]
    [Route("movies")]
    public class MovieController : ControllerBase
    {
        {seu_código_aqui}
    }

Raising Notifications

Entity Validation (Inheriting from EntityBase)

  public class MovieEntity :  EntityBase, IMovieContract
    {
        public MovieEntity(Guid id, string title, string description, DateTime realeaseDate)
        {
            Id = id;
            Title = title;
            Description = description;
            ReleaseDate = realeaseDate;

            Validate();

        }

        public override void Validate()
        {
            AddNotification("Title should not be null or empty", NotificationCode.TitleCantBeNullOrEmpty, Title);
        }
        ...   

Validating by context (INotifiable)

public class MovieUpdateService : IMovieUpdateService
    {
        public MovieUpdateService(IMovieWriteRepository movieWriteRepository, INotifiableContext notifiable, IMovieGetService movieGetService)
        {
            this.movieWriteRepository = movieWriteRepository;
            this.notifiable = notifiable;
            this.movieGetService = movieGetService;
        }
        private readonly IMovieWriteRepository movieWriteRepository;
        private readonly INotifiableContext notifiable;
        private readonly IMovieGetService movieGetService;

        public async Task<MovieResponse> UpdateMovieAsync(MovieUpdateRequest request)
        {
            try
            {

                var movieToUpdate = await movieGetService.GetMovieAsync(request.Id);

                if (movieToUpdate is null)
                {
                    notifiable.AddNotification(string.Empty, default, request.Id.ToString());
                    return default!;
                }

                if ((DateTime.MinValue.Date == request.ReleaseDate.Date) ||
                   (DateTime.Now.Date < request.ReleaseDate))
                {
                    notifiable.AddNotification(string.Empty, default, request.Id.ToString());
                    return default!;
                }
        ...   

Validating by contract

        public class MovieCreateService : IMovieCreateService
    {
        public MovieCreateService(IMovieWriteRepository movieWriteRepository, INotifiableContext notifiable, IMovieGetService movieGetService)
        {
            this.movieWriteRepository = movieWriteRepository;
            this.notifiable = notifiable;
            this.movieGetService = movieGetService;
        }
        private readonly IMovieWriteRepository movieWriteRepository;
        private readonly INotifiableContext notifiable;
        private readonly IMovieGetService movieGetService;

        public async Task<MovieResponse> CreateMovieAsync(MovieCreateRequest request)
        {
            try
            {
                var movieToCreate = await movieGetService.GetMovieAsync(request.Id);

                new Contract(notifiable)
                    .ShouldNotBeTrue(movieToCreate is not null, default)
                    .ShouldBeTrue(DateTime.MinValue.Date != request.ReleaseDate.Date, default)
                    .ShouldBeTrue(DateTime.Now.Date <= request.ReleaseDate.Date, default)
                    .ShouldNotBeTrue(string.IsNullOrWhiteSpace(request.Description),default);
        ...   

Validating entities

      internal class TestEntity : EntityBase
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }

        public TestEntity(string name, string adress)
        {
            Id = Guid.NewGuid();
            Name = name;
            Address = adress;

            Validate();
        }


        public override void Validate()
        {
            var contract = new Contract(this);

            contract.ShouldBeTrue(Comparator.String.IsNotNull(Name), NotificationCodes.NameCannotBeNull);
            contract.ShouldBeTrue(Comparator.String.HasLengthGreaterOrEqualThan(Name,3), NotificationCodes.NameCannotBeNull);
            contract.ShouldBeTrue(Comparator.String.IsNotNull(Address), NotificationCodes.AdressCannotBenull);
            contract.ShouldBeTrue(Comparator.String.HasLengthGreaterOrEqualThan(Address,15), NotificationCodes.AddressLengthShouldBeHigherOrEqualThan);

            //To Include em custom notification whitch was not previously registered

            AddNotification("Custom Message Here", default, Id.ToString());

        }
        
    }

    public class TestEntityNotifications
    {
        public static readonly Dictionary<long, NotificationParameters> Notifctions = new()
        {
            {
                NotificationCodes.NameCannotBeNull,
                new NotificationParameters(
                    "Name must be informed",
                    nameof(TestEntity.Name),
                    HttpStatusCode.UnprocessableEntity,
                    Enums.NotificationSeverity.Warning
                    )
            },
            {
                NotificationCodes.NameLengthShouldBeHigherOrEqualThan,
                new NotificationParameters(
                    "Name length should have length equal o greater than 3",
                    nameof(TestEntity.Name),
                    HttpStatusCode.UnprocessableEntity,
                    Enums.NotificationSeverity.Warning
                    )
            },
            {
                NotificationCodes.AdressCannotBenull,
                new NotificationParameters(
                    "Adress must be informed",
                    nameof(TestEntity.Address),
                    HttpStatusCode.UnprocessableEntity,
                    Enums.NotificationSeverity.Warning
                    )
            },
            {
                NotificationCodes.AddressLengthShouldBeHigherOrEqualThan,
                new NotificationParameters(
                    "Adress length should have length equal o greater than 15",
                    nameof(TestEntity.Address),
                    HttpStatusCode.UnprocessableEntity,
                    Enums.NotificationSeverity.Warning
                    )
            },
        };
    }

    public class NotificationCodes
    {
        public const long NameCannotBeNull = 1;
        public const long NameLengthShouldBeHigherOrEqualThan = 2;
        public const long AdressCannotBenull = 3;
        public const long AddressLengthShouldBeHigherOrEqualThan = 4;
    }

Usage example

This project has a micro api with an in-memory database exemplifying the use of the library.

Insomnia Example Api Collection

MIT License

Copyright (c) 2023

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.5 320 11/18/2023