GithubHelp home page GithubHelp logo

hakanucaar / optionable Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 23 KB

Add option ability to your class

Home Page: https://www.nuget.org/packages/Optionable/

License: MIT License

C# 100.00%
option option-pattern optionable

optionable's Introduction

Optionable

Add option ability to your class

Sample

Add an Option to FluentValidation Library

I want to added attribute option instead of RuleFor() method. https://github.com/FluentValidation/FluentValidation

Option defining

  public class AttributeOption : IOption
  {
      public bool UseNotNullAttribute { get; set; } = false;
  }

Attribute defining If my option is active I will use this attribute

    [AttributeUsage(AttributeTargets.Property)]
    public class NotNullAttribute : Attribute
    {

    }
  
    [AttributeUsage(AttributeTargets.Property)]
    internal class WithMessageAttribute : Attribute
    {
        public string Message { get; set; }
        public WithMessageAttribute(string message)
        {
            Message = message;
        }
    }

Classic FluentValidation sample class

    public class Customer
    {        
        public int Id { get; set; }
        //My Attribute
        [NotNull]
        public string Surname { get; set; }
        //My Attribute
        [NotNull]
        [WithMessage("Please specify a first name")]
        public string Forename { get; set; }
        public decimal Discount { get; set; }
        //My Attribute
        [NotNull]
        public string Address { get; set; }
    }

Implement IOptionable interface your base class

    public class OptionableValidator<T> : AbstractValidator<T>, IOptionable
    {
        public List<IOption> Options {get; set;} = new List<IOption>();
        public override ValidationResult Validate(ValidationContext<T> context)
        {
            this.UseNotNullAttribute(context);
            return base.Validate(context);
        }

        private void UseNotNullAttribute(ValidationContext<T> context)
        {
            //Get injected option
            var option = this.GetOption<AttributeOption>();
            if (option is not null && option.UseNotNullAttribute)
            {
                var props = context.InstanceToValidate.GetType().GetProperties();
                foreach (var prop in props)
                {
                    if (prop.GetCustomAttribute<NotNullAttribute>() is not null)
                    {
                        var param = Expression.Parameter(typeof(T));
                        var lambda = Expression.Lambda<Func<T, object>>((Expression)Expression.Property(param, prop.Name), param);

                        var withMessage = prop.GetCustomAttribute<WithMessageAttribute>();
                        if (withMessage is not null)
                        {
                            this.RuleFor<object>(lambda).NotNull().WithMessage(withMessage.Message);
                        }
                        else
                        {
                            this.RuleFor<object>(lambda).NotNull();
                        }
                    }
                }
            }
        }
    }
    public class CustomerValidator : OptionableValidator<Customer>
    {
        public CustomerValidator()
        {

        }
    }

Usage

    Customer customer = new Customer();
    CustomerValidator validator = new CustomerValidator();
    validator.AddOption<AttributeOption>(opt => opt.UseNotNullAttribute = true);

    ValidationResult results = validator.Validate(customer);

    if (!results.IsValid)
    {
        foreach (var failure in results.Errors)
        {
            Console.WriteLine("Property " + failure.PropertyName + " failed validation. Error was: " + failure.ErrorMessage);
        }
    }

    Console.ReadLine();

Output

Property Surname failed validation. Error was: 'Surname' boş olamaz.
Property Forename failed validation. Error was: Please specify a first name
Property Address failed validation. Error was: 'Address' boş olamaz.

optionable's People

Contributors

hakanucaar avatar

Watchers

 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.