Clone wiki

CodeCop / Fluent API

Fluent API

CodeCop also provides a Fluent API for those cases where it is more convenient to use a coding-style approach rather than an unobtrusive one. The API is very simple and is composed of these 5 methods:

AsFluent([optional]string key)

This method belongs to be Cop class and should be called when you want to work with this API instead of JSON. You should pass your product key as argument or else it will work on the Free product mode.

DecorateBefore(Action<InterceptionContext> before)

This is an extension method to MethodBase and should be used when you want to execute code before the intercepted method runs.

DecorateAfter(Action<InterceptionContext> after)

This is an extension method to MethodBase and should be used when you want to execute code after the intercepted method runs.

Override(Func<InterceptionContext, object> overrider)

This is an extension method to MethodBase and should be used when you want to override the intercepted method's code. It always should be called lastly on the fluent pipeline.

OnError(Action<InterceptionContext> handler)

This is an extension method to MethodBase and will be called whenever there is an error executing the intercepted method. Must be called before override.

Reset(MethodBase method)

This method belongs to be Cop class and should be called when you want remove all interceptors from a method, restoring it to its original state.

Here's an example of how you can execute code before, after and even overriding a method:

  static void Main(string[] args)
        {
            // Tell the runtime not to use JSON but instead use the Fluent API
            Cop.AsFluent();

            // Grab the method to intercept
            var method = typeof(Program).GetMethod("Method1");

            // Do your interception magic
            method
                .DecorateBefore((context) => Console.WriteLine("Before"))
                .DecorateAfter((context) => Console.WriteLine("After"))
                .OnError((context) =>
            {
                Console.WriteLine("Exception occurred {0}", Context.Exception.Message);
            })
                .Override((context) =>
            {
               Console.WriteLine("{0} was Overrided!", context.InterceptedMethod.Name);
               return null;
            });


            // Bootstrap CodeCop
            Cop.Intercept();

            // Call the intercepted method as you would normally would
            Method1();

        }

        public static void Method1()
        {
            Console.WriteLine("Method1");
        }
    }

You can even have multiple overriding logic and also the possibility to remove all interceptors from a method.

static void Main(string[] args)
        {
            // Tell the runtime not to use JSON but instead use the Fluent API
            Cop.AsFluent();

            // Grab the method to intercept
            var method = typeof(Program).GetMethod("Method1");

            // Do your overriding logic
            method
                .Override((context) =>
            {
               Console.WriteLine("Override1");
               return null;
            })

            // Bootstrap CodeCop
            Cop.Intercept();

            // Will output "Override1"
            Method1();

            // Do another overriding logic
            method
                .Override((context) =>
            {
               Console.WriteLine("Override2");
               return null;
            })

            // Call this method again to place the new overriding logic in place
            Cop.Intercept(); 

           // Will output "Override2"
            Method1();

            // Cleans all interceptors from a method, restoring it to its original state  
            Cop.Reset(method);

            // Will output "Method1"
            Method1();  
        }

        public static void Method1()
        {
            Console.WriteLine("Method1");
        }
    }

If you don't want to override the method, just want to execute code before, after and handle exceptions you should do like this:

  static void Main(string[] args)
        {
            // Tell the runtime not to use JSON but instead use the Fluent API
            Cop.AsFluent();

            // Grab the method to intercept
            var method = typeof(Program).GetMethod("Method1");

            // Do your interception magic
            method
                .DecorateBefore((context) => Console.WriteLine("Before"))
                .DecorateAfter((context) => Console.WriteLine("After"))
                .OnError((context, ex) =>
            {
                Console.WriteLine("Exception occurred {0}", ex.Message);
            });

            // Bootstrap CodeCop
            Cop.Intercept();

            // Call the intercepted method as you would normally would
            Method1();

        }

        public static void Method1()
        {
            Console.WriteLine("Method1");
        }
    }

NOTE: Please refer to the interceptors page for more details about the InterceptionContext object.

Pipelined Interception

From v1.3.0 onwards you can now also use Pipelined Interception on the Fluent API to intercept methods directly on interfaces and subsequently on all implementing types.

PipelineDecorate(Action<InterceptionContext> before, Action<InterceptionContext> after)

This is an extension method to Type and should be used on interfaces when you want to execute code before and / or after the intercepted method on implementing types runs.

PipelineOverride(Func<InterceptionContext, object> overrider)

This is an extension method to Type and should be used on interfaces when you want to override the intercepted method's code on implementing types.

PipelineOnError(Action<InterceptionContext> handler)

This is an extension method to Type and should be used on interfaces. It will be called whenever there is an error executing the intercepted method on implementing types. It always should be called lastly on the fluent pipeline.

// The type must be an interface
 typeof (IFoo)
                .PipelineDecorate((ctx) => Console.WriteLine("before"), (ctx) => Console.WriteLine("after"))
                .PipelineOverride((ctx) => { return null; })
                .PipelineOnError((ctx) => Console.WriteLine("bummm"));

Cop.Intercept();

// These types will be automatically intercepted as well.
new FooImplementor().Method1();
new AnotherFooImplementor().Method1();

Updated