GithubHelp home page GithubHelp logo

ziongh / stronglytypedid Goto Github PK

View Code? Open in Web Editor NEW

This project forked from andrewlock/stronglytypedid

0.0 0.0 0.0 3.16 MB

A Rosyln-powered generator for strongly-typed IDs

License: MIT License

C# 96.20% PowerShell 2.53% Shell 1.27%

stronglytypedid's Introduction

StronglyTypedId

StronglyTypedId logo

Build status NuGet MyGet CI

StronglyTypedId makes creating strongly-typed IDs as easy as adding an attribute! No more accidentally passing arguments in the wrong order to methods - StronglyTypedId uses Roslyn-powered build-time code generation to generate the boilerplate required to use strongly-typed IDs.

Simply, install the required packages add the [StronglyTypedId] attribute to a struct:

[StronglyTypedId] // <- Add this attribute to auto-generate the rest of the type
public partial struct FooId { }

and Roslyn magically generates the backing code when you save the file! Use Go to Definition to see the generated code:

Generating a strongly-typed ID using the StronglyTypedId packages

StronglyTypedId uses CodeGeneration.Roslyn by AArnott, which requires the .NET Core SDK v2.1+.

Installing

To use the the StronglyTypedId NuGet package you must add three packages:

To install the packages, add the references to your csproj file so that it looks something like the following:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>
  
  <!-- Add these three packages-->
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
    <PackageReference Include="StronglyTypedId" Version="0.2.0" />
  </ItemGroup>
  <!-- -->

</Project>

Restore the tools using dotnet restore.

Note that StronglyTypedId and CodeGeneration.Roslyn.Tool are build time dependencies - no extra dll's are added to your project's output! It's as though you wrote standard C# code yourself!

Usage

To create a strongly-typed ID, create a partial struct with the desired name, and decorate it with the [StronglyTypedId] attribute, in the global namespace:

[StronglyTypedId] // Add this attribute to auto-generate the rest of the type
public partial struct FooId { }

This generates the "default" strongly-typed ID using a Guid backing field, a custom TypeConverter, and a custom JsonConverter based on Newtonsoft.Json.

Removing the Newtonsoft.Json dependency

If you don't want to generate custom JsonConverters, set generateJsonConverter = false in the attribute constructor:

[StronglyTypedId(generateJsonConverter: false)] 
public partial struct NoJsonConverterId { }

If you don't generate a JsonConverter, you don't need the Newtonsoft.Json package dependency, and can remove it from your .csproj.

Generating a System.Text.Json JsonConverter

If you wish to generate a System.Text.Json JsonConverters, set jsonConverter = StronglyTypedIdJsonConverter.SystemTextJson in the attribute constructor:

[StronglyTypedId(jsonConverter: StronglyTypedIdJsonConverter.SystemTextJson)] 
public partial struct SystemTextJsonConverterId { }

If you wish, you can generate both a System.Text.Json and Newtonsoft.Json converter:

[StronglyTypedId(jsonConverter: StronglyTypedIdJsonConverter.NewtonsoftJson | StronglyTypedIdJsonConverter.SystemTextJson)] 
public partial struct BothJsonConverterId { }

Using different types as a backing fields

The default strongly-typed ID uses a Guid backing field:

[StronglyTypedId]
public partial struct FooId { }

var id = new FooId(Guid.NewGuid());

You can choose a different type backing field, by passing a value of the StronglyTypedIdBackingType enum in the constructor.

[StronglyTypedId(backingType: StronglyTypedIdBackingType.String)]
public partial struct FooId { }

var id = new FooId("my-id-value");

Currently supported values are Guid (the default), int, long, and string.

Why do I need this library?

I have written a blog-post series on strongly-typed IDs that explains the issues and rational behind this library. For a detailed view, I suggest starting there, but I provide a brief introduction here.

This library is designed to tackle a specific instance of primitive obsession, whereby we use primitive objects (Guid/string/int/long etc) to represent the IDs of domain objects. The problem is that these IDs are all interchangeable - an order ID can be assigned to a product ID, despite the fact that is likely nonsensical from the domain point of view. See here for a more concrete example.

By using strongly-typed IDs, we give each ID its own Type which wraps the underlying primitive value. This ensures you can only use the ID where it makes sense: ProductIds can only be assigned to products, or you can only search for products using a ProductId, not an OrderId.

Unfortunately, taking this approach requires a lot of boilerplate and ceremony to make working with the IDs manageable. This library abstracts all that away from you, by generating the boilerplate at build-time by using a Roslyn-powered code generator.

What code is generated?

The exact code generated depends on the arguments you provide to the StronglyTypedId attribute. The code is generated to the obj folder of the project, so you can use Go to Definition on your Id to see the exact code generated in each case.

You can see see example implementations in the templates folder:

Requirements

The StronglyTypedId NuGet package is a .NET Standard 2.0 package.

The code generation tool (CodeGeneration.Roslyn.Tool) is also required. These kind of tools are only supported in SDK-format csproj projects

The structs you decorate with the StronglyTypedId attribute must be marked partial.

Credits

StronglyTypedId wouldn't work if not for AArnott's CodeGeneration.Roslyn library.

The build process and general design of the library was modelled on the RecordGenerator project, which is similar to this project, but can be used to generate immutable Record types.

stronglytypedid's People

Contributors

andrewlock avatar vebbo2 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.