Skip to main content

Monify by Paul Martin

NuGet / site data​

Nuget GitHub last commit GitHub Repo stars

Details​

Info​

info

Name: Monify

Monify, a .NET Roslyn source generator, automates the creation of strongly-typed wrappers around single values, improving semantic clarity, type safety, and maintainability.

Author: Paul Martin

NuGet: https://www.nuget.org/packages/Monify/

You can find more details at https://github.com/MooVC/monify

Source: https://github.com/MooVC/monify

Author​

note

Paul Martin Alt text

Original Readme​

note

Monify NuGet GitHub

Monify, a .NET Roslyn source generator, automates the creation of strongly-typed wrappers around single values, improving semantic clarity, type safety, and maintainability.

Requirements​

  • C# v2.0 or later.
  • Visual Studio 2022 v17.4 or later, or any compatible IDE that supports Roslyn source generators.

Installation​

To install Monify, use the following command in your package manager console:

install-package Monify

Usage​

Monify turns a class, record, or struct into a strongly typed wrapper around a single value. To opt in, annotate a partial type with the Monify attribute and specify the encapsulated value type.

using Monify;

[Monify<int>]
public partial struct Age;

For language versions earlier than C# 11:

using Monify;

[Monify(Type = typeof(int))]
public partial struct Age;

Generated Members​

When applied, Monify generates the boilerplate needed for a lightweight value object:

  • A private readonly field _value that stores the encapsulated value.
  • A constructor accepting the underlying value: Age(int value).
  • Implicit conversion operators to and from the encapsulated type.
  • Implementations of IEquatable<Age> and IEquatable<int>.
  • Equality (==) and inequality (!=) operators for comparing with other instances or with the underlying value.
  • Overrides of Equals(object), GetHashCode(), and ToString().

Example​

Age age = 42;       // implicit conversion from int
int value = age; // implicit conversion to int

if (age == value)
{
// comparisons work with both Age and int
}

Classes annotated with Monify are sealed automatically to preserve immutability. Types must be partial and cannot declare additional state; the included analyzers will warn when these guidelines are not followed.

Nested wrappers and circular guards​

Monify also follows chains of nested wrappers and automatically emits the necessary implicit conversions so the outermost wrapper can convert directly to and from the innermost value type. For example, if Money wraps Amount and Amount wraps decimal, conversions will be generated for every hop, allowing callers to cast Money to decimal (and vice versa) without manual glue code.

To keep the generator safe, conversion discovery halts as soon as a type repeats in the chain. This prevents circular relationships (e.g. Outer wrapping Inner while Inner wraps Outer) from producing infinite loops or ambiguous operators while still supporting arbitrarily deep, non-circular nesting.

Analyzers​

Monify includes several analyzers to assist engineers with its usage. These are:

Rule IDCategorySeverityNotes
MONFY01UsageWarningType is not compatible with Monify
MONFY02UsageWarningType is not Partial
MONFY03DesignErrorType captures State
MONFY04DesignErrorSelf Referencing Type

Contributing​

Contributions are welcome - see the CONTRIBUTING.md file for details.

License​

This project is licensed under the MIT License - see the LICENSE.md file for details.

About​

note

Generate primitive strongly typed wrapper around a single value object

How to use​

Example (source csproj, source files)​

This is the CSharp Project that references Monify

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

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Monify" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>

Generated Files​

Those are taken from $(BaseIntermediateOutputPath)\GX

namespace Monify
{
using System;
using System.Diagnostics.CodeAnalysis;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
internal sealed class MonifyAttribute<T>
: Attribute
{
}
}

Useful​

Download Example (.NET C#)​

Share Monify​

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Monify

Category "PrimitiveObsession" has the following generators:​

1 DomainPrimitives NugetNuget GitHub Repo stars 2024-01-11

2 Monify Nuget GitHub Repo stars 2025-12-12

3 Strongly Nuget GitHub Repo stars 2023-08-19

4 StronglyTypedUid Nuget GitHub Repo stars 2024-04-07

5 UnitGenerator Nuget GitHub Repo stars 2023-10-15

6 Vogen Nuget GitHub Repo stars 2023-04-16

See category​

PrimitiveObsession