Wiki
Clone wikiCodeCop / 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:
#!c# 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"); } }
#!c# 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:
#!c# 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.
#!c# // 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