Code Monkey home page Code Monkey logo

typely's Introduction

build GitHub last commit codecov

Nuget version Nuget version Nuget version Nuget version Nuget version

Unleashing the power of domain primitives creation with a fluent Api. Based on a source generator and code analyzer.

Example

public class TypesSpecification : ITypelySpecification
{
    public void Create(ITypelyBuilder builder)
    {
        builder.OfInt().For("ContactId").GreaterThan(0);
        
        builder.OfString()
            .For("InsuranceCode")
            .Length(10)
            .Must(x => x.StartsWith("A91"))
            .Normalize(x => x.ToUpper());

        builder.OfString()
            .For("Phone")
            .MaxLength(12)
            .Matches(new Regex("[0-9]{3}-[0-9]{3}-[0-9]{4}"));
        
        var title = builder.OfString()
            .NotEmpty()
            .MaxLength(100)
            .Normalize(x => CultureInfo.InvariantCulture.TextInfo.ToTitleCase(x));

        title.For("FirstName");
        title.For("LastName");

        builder.OfDecimal()
            .For("CouponDiscount")
            .WithName("Coupon discount")
            .NotEmpty().WithMessage("{Name} cannot be empty").WithErrorCode("ERR-001")
            .GreaterThan(0).WithMessage(() => LocalizedMessages.CustomMessage)
            .LessThanOrEqualTo(24.99M);
    }
}

Documentation

Prerequisites

  • Supported .NET versions
    • .NET 7.0 and greater

Getting started

  1. Install packages

    dotnet add package Typely.Core
    dotnet add package Typely.Generators
    
  2. Create a class inheriting from ITypelySpecification

    public class TypesSpecification : ITypelySpecification
    {
        public void Create(ITypelyBuilder builder)
        {
            builder.OfString().For("FirstName").NotEmpty();    
        }
    }
  3. Usage

    var firstName = FirstName.From("Adam");
    FirstName.From(""); //Throws ValidationException
    
    if(!FirstName.TryFrom("value", out FirstName instance, out ValidationError? validationError))
    {
        // Handle error
    }

Json Serialization

Serialization using System.Text.Json is supported by default and will only write the underlying value.

ASP.NET Core

Nuget version

To support validation handling and MVC model binding, include Typely.AspNetCore in your projects.

Nuget package

dotnet add package Typely.AspNetCore

Model binding

  • By default Minimal Apis are supported by implementing a TryParse function for generated types.
  • Post requests are supported by TypelyJsonConverter.
  • Other bindings are supported by TypelyTypeConverter.

These are included by default with Typely.Core.

Model state

If you want to add validation errors into the model state of MVC during the binding phase of the request, configure the option below:

Configuration

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options => options.UseTypelyModelBinderProvider());

It supports many validation errors without using exceptions.

Validation errors

The following middleware allows you to return neatly structured Json error responses compatible with Microsoft.AspNetCore.Http.HttpValidationProblemDetails.

Configuration

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Register this middleware before other middleware components
app.UseTypelyValidationResult();

It works by catching a ValidationException thrown by Typely and returns a list of errors associated to their value object type name as well as the templates used, if you want to modfify the messages in your client application.

Example of response:

{
  "templates": {
    "ZipCode": [
      {
        "code": "Matches",
        "message": "'{Name}' is not in the correct format. Expected format '{RegularExpression}'.",
        "typeName": "ZipCode",
        "placeholderValues": {
          "RegularExpression": "^((\\d{5}-\\d{4})|(\\d{5})|([A-Z|a-z]\\d[A-Z|a-z]\\d[A-Z|a-z]\\d))$",
          "Name": "ZipCode",
          "ActualLength": "7"
        }
      }
    ]
  },
  "errors": {
    "ZipCode": [
      "'ZipCode' is not in the correct format. Expected format '^((\\d{5}-\\d{4})|(\\d{5})|([A-Z|a-z]\\d[A-Z|a-z]\\d[A-Z|a-z]\\d))$'."
    ]
  },
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400
}

OpenAPI

Nuget version

To add support for OpenAPI specs and Swagger UI, include Typely.AspNetCore.Swashbuckle in your projects.

Nuget package

dotnet add package Typely.AspNetCore.Swashbuckle

Configuration

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwaggerGen(options => options.UseTypelySchemaFilter());

Entity Framework Core

Nuget version

To use your value objects with EF Core, include Typely.EfCore in your projects.

Nuget package

dotnet add package Typely.EfCore

Configuration

Apply Typely conventions to your DbContext to automatically configure the database. By default, the conventions will tell EF Core how to save and load your value objects and set the maximum data length.

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
    configurationBuilder.Conventions.AddTypelyConventions();
    //OR
    configurationBuilder.Conventions
        .AddTypelyConversionConvention()
        .AddTypelyMaxLengthConvention();
}

If you don't use conventions, you can configure your types manually. Typely will generate a MaxLength property when using a validation that sets the maximum length.

builder.Property(x => x.LastName)
    .HasMaxLength(LastName.MaxLength)
    .HasConversion<TypelyValueConverter<string, LastName>>();

You can also override the default conventions:

builder.Property(x => x.FirstName)
    .HasMaxLength(80)
    .HasConversion((x) => x + "-custom-conversion", (x) => FirstName.Create(x.Replace("-custom-conversion", "")));

typely's People

Contributors

adampaquette avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

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.