{"id":40,"date":"2012-10-21T15:13:00","date_gmt":"2012-10-21T15:13:00","guid":{"rendered":"http:\/\/tpodolak.com.hostingasp.pl\/blog\/2012\/10\/21\/argument-validation-with-attributes-and-ninject-interceptor\/"},"modified":"2016-01-31T00:04:56","modified_gmt":"2016-01-31T00:04:56","slug":"argument-validation-with-attributes-and-ninject-interceptor","status":"publish","type":"post","link":"https:\/\/tpodolak.com\/blog\/2012\/10\/21\/argument-validation-with-attributes-and-ninject-interceptor\/","title":{"rendered":"Argument validation with attributes and Ninject interceptor"},"content":{"rendered":"<h3>1. Introduction<\/h3>\n<p>It is a common practice to validate function arguments before running actual code. Usually validation looks like that:<\/p>\n<pre lang=\"csharp\">\r\npublic  void Update(Car entity)\r\n{\r\n    if(entity ==null)\r\n        throw new ArgumentNullException(\"entity\");\r\n}\r\n<\/pre>\n<p>There is nothing wrong with this code, however we have to repeat this piece of code in every function. Of course we could create some helper class for argument validation and call approperiate validation function before launching rest of the code<\/p>\n<pre lang=\"csharp\">\r\npublic static class ValidationHelper\r\n{\r\n    public static void CheckNotNull(object entity, string argumentName)\r\n    {\r\n        if (entity == null)\r\n            throw new ArgumentNullException(argumentName);\r\n    }\r\n}\r\n\r\npublic  void Update(Car entity)\r\n{\r\n    ValidationHelper.CheckNotNull(entity, \"entity\");\r\n    \/\/rest of the code\r\n}\r\n<\/pre>\n<p>However I was searching for more universal way for argument validation. That is why, I decided to try function interceptors and attributes.<\/p>\n<h3>2. Creating validation attributes<\/h3>\n<p>Let&#8217;s start for creating base attribute<\/p>\n<pre lang=\"csharp\">\r\n[AttributeUsage(AttributeTargets.Parameter)]\r\npublic abstract class ArgumentValidationAttribute : Attribute\r\n{\r\n    public abstract void ValidateArgument(object value, string argumentName);\r\n}\r\n<\/pre>\n<p>In the next step let&#8217;s create specialized attribute for &#8220;not null&#8221; validation. This argument may look this way:<\/p>\n<pre lang=\"csharp\">\r\npublic class NotNullAttribute : ArgumentValidationAttribute\r\n{\r\n    public override void ValidateArgument(object value,string argumentName)\r\n    {\r\n        if (value == null)\r\n            throw new ArgumentNullException(argumentName, string.Format(\"Value {0} can not be null\", argumentName));\r\n    }\r\n}\r\n<\/pre>\n<h3>3. Using IInterceptor interface<\/h3>\n<p>That was an easy part, now it&#8217;s necessary to somehow intercept function execution and run attribute validation.In .NET there is no build-in mechanism to do that,that is why I&#8217;ll use extension for Ninject &#8211; Ninject Interception. First of all we have to add to our project three dll&#8217;s<\/p>\n<ul>\n<li>Ninject<\/li>\n<li>Ninject.Extensions.Interception<\/li>\n<li>Ninject.Extensions.Interception.LinFu<\/li>\n<\/ul>\n<p>You can easily add them using NuGet. Having all necessary files added to solution,let&#8217;s create function interceptor &#8211; <i>ValidaitionInterceptor<\/i>.<\/p>\n<pre lang=\"csharp\">\r\npublic class ValidationInterceptor : IInterceptor\r\n{\r\n    public void Intercept(IInvocation invocation)\r\n    {\r\n        var parameters = invocation.Request.Method.GetParameters();\r\n        for (int index = 0; index < parameters.Length; index++)\r\n        {\r\n            foreach (ArgumentValidationAttribute attr in parameters[index].GetCustomAttributes(typeof(ArgumentValidationAttribute), true))\r\n                attr.ValidateArgument(invocation.Request.Arguments[index], parameters[index].Name);\r\n        }\r\n        invocation.Proceed();       \r\n    }\r\n}\r\n<\/pre>\n<p>As You can see <i>ValidationInterceptor<\/i> implements interface <i>IInterceptor<\/i>which belongs to <i>Ninject.Extensions.Interception<\/i>. This interface has one method <i>Intercept<\/i> which is called before function from registered component is called. In this function I iterate over all function attributes of type ArgumentValidationAttribute and call <i>ValidateArgument<\/i> function. If validation passess function <i>invocation.Proceed()<\/i> is called, which continues execution of original function.<\/p>\n<h3>4. Example of usage<\/h3>\n<p>In order to take advantage of benefits of function interceptors, we have to resolve objects from Ninject container. First of all I'll create some examplorary classes<\/p>\n<pre lang=\"csharp\">\r\npublic interface IRepository<T> where T:class\r\n{\r\n    List<T> GetAll();\r\n    void Update([NotNull] T entity);\r\n}\r\n\r\npublic class Car\r\n{\r\n    public int Id { get; set; }\r\n    public string Model { get; set; }\r\n}\r\n\r\npublic class CarRepository : IRepository<Car>\r\n{\r\n    public  List<Car> GetAll()\r\n    {\r\n        return null;\r\n    }\r\n\r\n    public  void Update(Car entity)\r\n    {\r\n            \r\n    }\r\n}\r\n<\/pre>\n<p>In the next step I'll create simple wrapper for Ninject container and register CarRepository in Kernel<\/p>\n<pre lang=\"csharp\">\r\npublic static class IOCContainer\r\n{\r\n    private static readonly IKernel Kernel;\r\n    static IOCContainer()\r\n    {\r\n        Kernel = new StandardKernel();\r\n    }\r\n\r\n    public static void Configure()\r\n    {\r\n        Kernel.Bind(typeof(IRepository<Car>)).To(typeof(CarRepository)).Intercept().With<ValidaitionInterceptor>();\r\n    }\r\n\r\n    public static T Get<T>()\r\n    {\r\n        return Kernel.Get<T>();\r\n    }\r\n}\r\n<\/pre>\n<p>Please, notice that registration of <i>CarRepository<\/i> was used with option <i>Intercept().With<ValidaitionInterceptor>()<\/i>. Thanks to this configuration,everytime we call method from CarRepository, <i>Intercept<\/i> method from <i>ValidaitionInterceptor<\/i> will be called first. Now, it is time to use our repository,we could do that this way<\/p>\n<pre lang=\"csharp\">\r\nclass Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        IOCContainer.Configure();\r\n        var carRepository = IOCContainer.Get<IRepository<Car>>();\r\n        carRepository.Update(null);\r\n    }\r\n}\r\n<\/pre>\n<p>Argument <i>entity<\/i> in method <i>Update<\/i> from interface <i>IRepository<\/i> was decorated with <i>NotNull<\/i>, that is why our validation mechanism should throw exception.<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/CallingValidationInInterceptor.png\" rel=\"attachment wp-att-377\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/CallingValidationInInterceptor.png\" alt=\"CallingValidationInInterceptor\" width=\"800\" class=\"aligncenter size-full wp-image-377\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/CallingValidationInInterceptor.png 1153w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/CallingValidationInInterceptor-150x45.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/CallingValidationInInterceptor-300x91.png 300w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/CallingValidationInInterceptor-1024x309.png 1024w\" sizes=\"(max-width: 1153px) 100vw, 1153px\" \/><\/a><br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/Throw.png\" rel=\"attachment wp-att-378\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/Throw.png\" alt=\"Argument validation\" width=\"800\" class=\"aligncenter size-full wp-image-378\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/Throw.png 1023w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/Throw-150x79.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/10\/argument-validation-with-attributes-and-ninject-interceptor\/Throw-300x157.png 300w\" sizes=\"(max-width: 1023px) 100vw, 1023px\" \/><\/a><\/p>\n<h3>5. Validation of return value<\/h3>\n<p>Using <i>IInterceptor<\/i> we could go one step further and also validate return value of method. In order to do that, we have to slightly modify <i>Intercept<\/i> method in <i>ValidaitionInterceptor<\/i> class.<\/p>\n<pre lang=\"csharp\">\r\npublic class ValidaitionInterceptor : IInterceptor\r\n{\r\n    public void Intercept(IInvocation invocation)\r\n    {\r\n        var parameters = invocation.Request.Method.GetParameters();\r\n        for (int index = 0; index < parameters.Length; index++)\r\n        {\r\n            foreach (ArgumentValidationAttribute attr in parameters[index].GetCustomAttributes(typeof(ArgumentValidationAttribute), true))\r\n                attr.ValidateArgument(invocation.Request.Arguments[index], parameters[index].Name);\r\n        }\r\n\r\n        invocation.Proceed();\r\n\r\n        foreach (ArgumentValidationAttribute attr in invocation.Request.Method.ReturnTypeCustomAttributes.GetCustomAttributes(typeof(ArgumentValidationAttribute), true))\r\n        {\r\n            attr.ValidateArgument(invocation.ReturnValue, \"return value\");\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>We also have to change attribute usage of <i>ArgumentValidationAttribute<\/i> to<\/p>\n<pre lang=\"csharp\">\r\n[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.ReturnValue)]\r\n<\/pre>\n<p>Now, we can decorate function <i>GetAll<\/i> with <i>NotNull<\/i>attribute<\/p>\n<pre lang=\"csharp\">\r\n[return: NotNull]\r\nList<T> GetAll();\r\n<\/pre>\n<p>Since this moment, everytime function <i>GetAll<\/i> returns null, the ArgumentNullException will be thrown.<\/p>\n<h3>6. Drawbacks<\/h3>\n<p>Unfortunately using attributes for argument validation have some drawbacks. First of all, argument validation is based on function interceptors, and as I mentioned before only function, which are in objects, which are resolved from IoC container can be intercepted. What is more, interceptors allow us to intercept only functions marked as virtual or inhirited from interface. Source code for this post can be found <a href=\"https:\/\/github.com\/tpodolak\/Blog\/tree\/master\/NInjectInterceptors\">here<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. Introduction It is a common practice to validate function arguments before running actual code. Usually validation looks like that: public void Update(Car entity) { if(entity ==null) throw new ArgumentNullException(&#8220;entity&#8221;); } There is nothing wrong with this code, however we have to repeat this piece of code in every function. Of course we could create [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,54,3,88,85,86,84],"tags":[160,200,159,226,227,228,229],"class_list":["post-40","post","type-post","status-publish","format-standard","hentry","category-net","category-attributes","category-c","category-interceptor","category-ninject","category-ninject-extensions","category-validation","tag-net","tag-attributes","tag-c","tag-interceptor","tag-ninject","tag-ninject-extensions","tag-validation"],"_links":{"self":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/40","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/comments?post=40"}],"version-history":[{"count":5,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/40\/revisions"}],"predecessor-version":[{"id":546,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/40\/revisions\/546"}],"wp:attachment":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/media?parent=40"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/categories?post=40"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/tags?post=40"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}