Skip to content

Witness is a .NET Core micro-framework for building object validation in fluent style

License

Notifications You must be signed in to change notification settings

MrZoidberg/Witness

Repository files navigation

Witness

GitHub Workflow Status Codacy Badge Nuget

Witness is a small vaidation library for .NET Core that allows building object validation in a fluent style. It is mostly targets custom validation rules that are very hard to implement in existing solutions like Fluent Validation.

Features:

  • Fully fluent-style based on pure functions
  • DI inside validation rules
  • Conditional branches with .If

Get Started

Witness can be installed using the Nuget package manager or the dotnet CLI.

dotnet add package WitnessValidation

If you need to use DI for validation add the following package:

dotnet add package WitnessValidation.DependencyInjectionExtensions

Example

using Witness;

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }
    
    public uint Age { get; set; }
    
    public string GithubAccount { get; set; }
}


public static class PersonValidationRulesExtensions
{    
    [Pure]
    public static Func<IValidationContext<Person, string>> ShouldExistInGithub(this Func<IValidationContext<Person, string>> context)
    {
        return () =>
        {
            var c = context();

            bool isValid = !string.IsNullOrEmpty(c.OUV);
            if (isValid)
            {
                using HttpClient client = new HttpClient();
                var result = new TaskFactory(TaskScheduler.Current)
                    .StartNew(async () => await client.GetAsync($"https://github.com/{c.OUV}"))
                    .Unwrap()
                    .GetAwaiter()
                    .GetResult();

                isValid = result.StatusCode != HttpStatusCode.NotFound;
            }

            if (!isValid)
            {
                c.ValidationErrors.Add($"{c.OUVName} should be a valid Github username");
            }

            return c;
        };
    }
}

Person person = new Person()
{
    FirstName = "Joe",
    LastName = string.Empty,
    Age = 5,
    GithubAccount = "test",
};

var result = person
    .Validate()
    .RuleFor(c => c.FirstName).ShouldNotBeEmptyOrNull()
    .And()
    .RuleFor(c => c.LastName).ShouldNotBeEmptyOrNull()
    .And()
    .RuleFor(c => c.Age).ShouldBeInRange(18, 100)
    .And()
    .RuleFor(c => c.GithubAccount).ShouldExistInGithub()
    .Execute();

DI Example

public static class PersonValidationRulesExtensions
{
    [Pure]
    public static Func<IValidationContext<Person, string>> ShouldExistInGithub(this Func<IValidationContext<Person, string>> context)
    {
        return () =>
        {
            var c = context();

            bool isValid = !string.IsNullOrEmpty(c.OUV);
            if (isValid)
            {
                var githubService = c.Resolve<IGithubService>();
                isValid = githubService.IsUserExists(c.OUV);
            }

            if (!isValid)
            {
                c.ValidationErrors.Add($"{c.OUVName} should be a valid Github username");
            }

            return c;
        };
    }
}

Person person = new Person()
{
    FirstName = "Joe",
    LastName = string.Empty,
    Age = 5,
    GithubAccount = "test",
};

var serviceProviderCollection = new ServiceCollection();
serviceProviderCollection.AddTransient<IGithubService, GithubService>();
IServiceProvider serviceProvider = serviceProviderCollection.BuildServiceProvider();

var result = person
    .Validate()
    .WithServiceProvider(serviceProvider)
    .FirstName().ShouldNotBeEmptyOrNull()
    .And()
    .LastName().ShouldNotBeEmptyOrNull()
    .And()
    .Age().ShouldBeInRange(18, 100)
    .And()
    .GithubAccount().ShouldExistInGithub()
    .Execute();

About

Witness is a .NET Core micro-framework for building object validation in fluent style

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published