All Projects → Singulink → RuntimeNullables

Singulink / RuntimeNullables

Licence: MIT license
Automatic null check injection for runtime C# 8+ Nullable Reference Type (NRT) contract validation.

Programming Languages

C#
18002 projects

Projects that are alternatives of or similar to RuntimeNullables

MethodBoundaryAspect.Fody
A Fody weaver which allows to decorate methods and hook into method start, method end and method exceptions.
Stars: ✭ 173 (+620.83%)
Mutual labels:  aop
thinking-in-spring
Spring source code reading
Stars: ✭ 105 (+337.5%)
Mutual labels:  aop
Spring
Personal notes of preparation to Spring 5 Professional Certification
Stars: ✭ 35 (+45.83%)
Mutual labels:  aop
CSharpCampReCapProject
Kodlama.io | C# Camp | Recap Project | Car Rental System | 2021
Stars: ✭ 17 (-29.17%)
Mutual labels:  aop
rocket-pipes
Powerful pipes for TypeScript, that chain Promise and ADT for you 🚌 -> ⛰️ -> 🚠 -> 🏂 -> 🚀
Stars: ✭ 18 (-25%)
Mutual labels:  aop
DRouter
简单易用的支持多进程架构的组件化方案
Stars: ✭ 74 (+208.33%)
Mutual labels:  aop
CrmWebApi
🎉 CRM后台管理系统(后端 WebApi)
Stars: ✭ 13 (-45.83%)
Mutual labels:  aop
Decor.NET
A simple way to decorate a class with additional functionality using attributes.
Stars: ✭ 29 (+20.83%)
Mutual labels:  aop
egg-aop
AOP plugin for eggjs, add DI, AOP support.
Stars: ✭ 44 (+83.33%)
Mutual labels:  aop
metrics-aspectj
AspectJ integration for Dropwizard Metrics
Stars: ✭ 78 (+225%)
Mutual labels:  aop
tiny4j
IOC, AOP, REST...
Stars: ✭ 15 (-37.5%)
Mutual labels:  aop
metrics-spring-boot
Spring Boot 基于Sentinel服务接口监控及其手自一体化限流
Stars: ✭ 17 (-29.17%)
Mutual labels:  aop
live-platform
Add breakpoints, logs, metrics, and spans to live production applications
Stars: ✭ 37 (+54.17%)
Mutual labels:  aop
LSFramework
手写山寨版spring学习aop、ioc思想的demo,没看过spring的源码,因为实在是太庞大了,参考部分网上博客及开源代码完成。
Stars: ✭ 53 (+120.83%)
Mutual labels:  aop
android-aop-analytics
Demo application that implements Google Analytics tracking in an aspect-oriented way using AspectJ.
Stars: ✭ 31 (+29.17%)
Mutual labels:  aop
hasor
Hasor是一套基于 Java 语言的开发框架,区别于其它框架的是 Hasor 有着自己一套完整的体系,同时还可以和先有技术体系做到完美融合。它包含:IoC/Aop容器框架、Web框架、Jdbc框架、RSF分布式RPC框架、DataQL引擎,等几块。
Stars: ✭ 938 (+3808.33%)
Mutual labels:  aop
ComposableAsync
Create, compose and inject asynchronous behaviors in .Net Framework and .Net Core.
Stars: ✭ 28 (+16.67%)
Mutual labels:  aop
small-spring
🌱《 Spring 手撸专栏》,本专栏以 Spring 源码学习为目的,通过手写简化版 Spring 框架,了解 Spring 核心原理。在手写的过程中会简化 Spring 源码,摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。
Stars: ✭ 3,277 (+13554.17%)
Mutual labels:  aop
Cauldron
C# Toolkit
Stars: ✭ 68 (+183.33%)
Mutual labels:  aop
instrumentation
An extensible java agent framework that instruments (modifies the bytecode at class loading time) programs running on the JVM, with the purpose of capturing method invocation events (start, finish, errors ...) and notifying custom listeners.
Stars: ✭ 39 (+62.5%)
Mutual labels:  aop

Runtime Nullables

Chat on Discord View nuget packages Build and Test

Runtime Nullables automatically adds null checks to method/property entry and exit points based on the standard nullable annotations and attributes available in C# 8+. It is capable of checking input parameters as well as outputs (i.e. return values and out/ref parameters) and supports comprehensive checks on the full range of special method types including asynchronous Task<T> methods, Task<T> methods that synchronously return completed tasks (i.e. using Task.FromResult<T>), IEnumerable<T>/IEnumerator<T> iterators as well as asynchronous IAsyncEnumerable<T>/IAsyncEnumerator<T> iterators. Custom throw helpers can be defined to fully customize the exceptions thrown to your liking.

About Singulink

We are a small team of engineers and designers dedicated to building beautiful, functional and well-engineered software solutions. We offer very competitive rates as well as fixed-price contracts and welcome inquiries to discuss any custom development / project support needs you may have.

Visit https://github.com/Singulink to see our full list of publicly available libraries and other open-source projects.

Installation

The package is available on NuGet - simply install the RuntimeNullables.Fody package into your project and null checks will be automatically injected when your project builds! It is also a good idea to add the latest Fody package directly to your project to ensure you are using an up-to-date version to avoid issues.

Runtime Nullables v.s. NullGuard.Fody

After adding nullable annotation support to NullGuard on top of its legacy functionality, it was apparent that it become rather unweildy. This made expanding features and optimizing behavior for nullable annotations difficult in addition to inheriting an overly complex attribute model. Runtime Nullables was written from the ground up with only nullable annotations in mind to address these issues. Some notable improvements include:

  • More efficient weaving algorithm for faster build times.
  • Does not force .initlocals on methods (better performance, especially with stackalloc).
  • Supports checking ValueTask<T> results, synchronously returned complete Task<T> results, IEnumerable<T>/IEnumerator<T> iterator values and asynchronous IAsyncEnumerable<T>/IAsyncEnumerator<T> iterator values.
  • Uses throw helpers instead of throwing directly (better performance / smaller IL code) and lets you define your own custom throw helpers.
  • Much simpler attribute model that uses a single [NullChecks(bool)] attribute to control null check injection.
  • Designed specifically for NRTs so it is much easier to add advanced functionality such as full validation of conditional attributes like [MaybeNullWhen] (planned for a future release).
  • Outputs warnings for conflicting annotations that cause null checks to be skipped, i.e. if [AllowNull, DisallowNull] is applied to a parameter.
  • Uses NullReferenceException instead of InvalidOperationException when an output check fails since the latter is often thrown/caught in normal circumstances which can cause null contract violations to go unnoticed in unit tests or exception handling code.
  • Numerous bug fixes and reliability improvements.

Configuration

By default, null checks are added based on the build configuration as follows:

  • Release: input parameter values on publicly exposed methods/properties only
  • Debug: input and output (ref/out) parameter values and return values on all methods/properties

The behavior can be configured in one of two ways: inside your .csproj file or using a FodyWeavers.xml configuration file in the root of your project. There are two configuration settings:

  • CheckOutputs: If set to true then outputs (i.e. return values, ref/out parameters) will be null checked, otherwise these checks are omitted.
  • CheckNonPublic: If set to true then all methods/properties are checked, otherwise only those that are potentially publicly exposed are checked.

If configuring via the .csproj file then you have to add a <WeaverConfiguration> property like so:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <WeaverConfiguration>
      <Weavers>
        <RuntimeNullables CheckNonPublic="true" CheckOutputs="true" />
      </Weavers>
    </WeaverConfiguration>
  </PropertyGroup>
</Project>

If you would like to configure settings with a FodyWeavers.xml file in the project then simply build the project after adding the RuntimeNullables.Fody package and it will automatically generate an xml configuration file for you which you can then edit. Alternatively, you can add the file manually with the following contents:

<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
  <RuntimeNullables CheckNonPublic="true" CheckOutputs="true" />
</Weavers>

If you omit the CheckNonPublic or CheckOutputs setting then it will fallback to the default behavior based on the build configuration as explained above.

Fine-Tuning Behavior

Injection of null checks can be fine-tuned in your code using the [NullChecks(bool)] attribute which can be applied at the assembly, class, method/property or return value level. For example, if you apply [NullChecks(false)] to a class it will disable null checks on every member in that class unless it has [NullChecks(true)] applied to it. It is important to note that if the CheckOutputs or CheckNonPublic setting is false then that will override any [NullChecks(true)] attribute applied to an output or non-public member. In other words, if the setting is set to false then those particular checks are never emitted, regardless of the presence of a [NullChecks(true)] attribute.

Additionally, custom throw helpers can be defined to customize the exceptions that are thrown. In order to do that, you simply add an internal ThrowHelpers class into your project in the RuntimeNullables namespace and match the signature of the throw helper you want to override and it will be used instead of the defaults. The default throw helpers are as follows:

namespace RuntimeNullables
{
    internal static class ThrowHelpers
    {
        internal static void ThrowArgumentNull(string paramName)
        {
            throw new ArgumentNullException(paramName);
        }

        internal static void ThrowOutputNull(string message)
        {
            throw new NullReferenceException(message);
        }

        internal static Exception GetAsyncResultNullException(string message)
        {
            return new NullReferenceException(message);
        }
    }
}

If an output check or async result check fails then the message parameter contains a message specifying exactly what caused the check to fail, i.e. "Enumerator result nullability contract was broken."

Examples

using RuntimeNullables;

// Return value is not null checked since it is nullable,
// but method throws ArgumentNullException if messageService is null
public string? GetMessage(MessageService messageService);

// The 'value' parameter is null checked on method entry as well as when the method exits since it is a ref
public void UpdateMessage(ref string value);

// Now the 'value' parameter is only null checked on method entry due to the [MaybeNull] annotation
public void UpdateMessage([MaybeNull] ref string value);

// Each item returned by the enumeration is null checked
public IEnumerable<string> GetMessages()
{
    string? nullValue = null;
    yield return "some value";
    yield return "some other value";
    yield return nullValue!; // NullReferenceException is thrown
}

public Task<T> GetValueAsync<T>()
{
    return Task.FromResult<T>(default!); // NullReferenceException if T is a reference type
}

[return: NullChecks(false)]
public Task<T> GetValueAsync<T>()
{
    return Task.FromResult<T>(default!); // This is okay now since return value null checks are disabled
}

// Result of the task is null checked
public async Task<string> GetMessageAsync()
{
    return await MessageService.GetMessageAsync();
}

// All results are null checked
public async IAsyncEnumerable<string> GetValuesAsync()
{
    await Task.Delay(100);
    yield return "Some value";
    await Task.Delay(100);
    yield return null!; // NullReferenceException is thrown
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].