MVP Award Renewed

It was with great pleasure that I read Microsoft’s email today announcing me that I had renewed as MVP for the third year!

image

Being an MVP is both an honor and a privilege, and I feel both proud and humble to again be a part of this fantastic group of people! Thanks, Cristina, for this!

I also want to congratulate all of the other Portuguese MVPs that were renewed this year, and leave a word of comfort to those who haven’t. All the best, guys (and lady)! Winking smile

2016 in Review

Another year is over, time to review what I did this time… so here it goes:

Some trends:

Not all was good, though… was unable to finish on time an article for a development magazine… and was late on delivering another ebook… and couldn’t start another book, due to pure lack of time… more news on the first two next year, hopefully!

Next year I imagine I will be writing more and more on .NET Core and specifically ASP.NET Core. Probably some Elasticsearch and Docker (new!) too. Some “classic” topics will have more contents soon:

Azure and AWS will probably pop up too. Too soon to tell!

Anyway, I wish you all an excellent 2017! Thanks for visiting me, keep dropping by! Winking smile

Entity Framework Core Cookbook – Second Edition

Some of you may be aware that my new book for Packt Publishing is out! It is titled Entity Framework Core Cookbook – Second Edition because it was meant to be the second edition of Entity Framework 4.1: Expert’s Cookbook. In fact, it is mostly a full rewrite.

It is organized in chapters:

Chapter 1: Improving Entity Framework in the Real World

Chapter 2: Mapping Entities

Chapter 3: Validation and Changes

Chapter 4: Transactions and Concurrency Control

Chapter 5: Querying

Chapter 6: Advanced Scenarios

Chapter 7: Performance and Scalability

Appendix: Pitfalls

When I started writing it, .NET Core was still in early RC1. Things changed a lot from RC1 to RC2 and then again to RTM, so I had to revisit all chapters in the end. It was a pity that EF Core 1.1 was released shortly after the book was closed, because I could have talked about it too. Also, there are things that I could have covered, like extending Entity Framework Core, but there were so many of them! Smile Maybe in a future time!

Those of you who are interested can get a copy from the Pack Publishing site or from other sellers, either as an e-book or in hardcopy.

I want to thank everyone at Packt Publishing, namely Chaitanya Nair, Merint Mathew and Siddhi Chavan for their professionalism and support!

What’s New in .NET Core 1.1

.NET Core 1.1 – including ASP.NET Core and Entity Framework Core – was just released at the time of the Connect(); event. With it came some interesting features and improvements.

Before you start using version 1.1 you need to make sure you install the .NET Core 1.1 SDK from https://www.microsoft.com/net/download/core. If you don’t, some stuff will not work properly.

Here are some highlights.

ASP.NET Core

In version 1.1 you can now treat View Components like Tag Helpers! Not sure why they did this, but I guess it’s OK.

You new have URL rewriting middleware that can consume the same configuration file as the IIS URL Rewrite Module.

Also new is Caching middleware, bringing what was Output Cache in ASP.NET Web Forms to Core Land.

GZip compression is also starring as a middleware component.

Middleware components can now be applied as global attributes. Seems interesting, but I don’t know how this works, because we can’t specify the ordering.

Next big thing is WebListener. It’s another HTTP server, but this time tuned for Windows. Because it this, it supports Windows authentication, port sharing, HTTPS with Server Name Indication (SNI), HTTP/2 over TLS (on Windows 10), direct file transmission, and response caching WebSockets (on Windows 8 or higher).

Temp data can now be stored in a cookie, as with MVC pre-Core.

You can now log to Azure App Service and you can also get configuration information from Azure Key Vault. Still on Azure, you can make use of Redis and Azure Storage Data Protection.

Finally, something that was also previously available is view precompilation. Now you can build your views at compile time and get all errors ahead of time.

Not all is here, though: for example, mobile views are still not available.

More on https://blogs.msdn.microsoft.com/webdev/2016/11/16/announcing-asp-net-core-1-1 and https://github.com/aspnet/home/releases/1.1.0.

Entity Framework Core

The Find method is back, allowing us to load entities by their primary keys. As a side note, I have published a workaround for this for the initial version of EF Core 1.0. Same for Reload, GetModifiedProperties and GetDatabaseValues.

Explicit loading for references and collections is also here.

Connection resiliency, aka, the ability to retry a connection, also made its move to version 1.1, similar to what it was in pre-Core.

Totally new is the support for SQL Server’s Memory Optimized Tables (Hekaton).

Now we can map to fields, not just properties! This was an often requested feature, which helps follow a Domain Driven Design approach.

Also new is the capacity to change a specific service implementation without changing the whole service provider at startup.

There are more API changes and apparently LINQ translation has improved substantially. Time will tell!

A lot is still missing from pre-Core, see some of it here.

More info here: https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1 and here: https://github.com/aspnet/EntityFramework/releases/tag/rel%2F1.1.0.

.NET Core

First of all, .NET Core 1.1 can now be installed in more Linux distributions than before and also in MacOS 10 and in Windows Server 2016.

The dotnet CLI has a new template for .NET Core projects.

.NET Core 1.1 supports .NET Standard 1.6.

Lots of performance improvements, bug fixes and imported APIs from .NET full.

Read more about it here: https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-net-core-1-1/ and here: https://github.com/dotnet/core/tree/master/release-notes/1.1.

Interception in .NET – Part 4: An Interception Framework

Introduction

This is the fourth and possibly final post on my interception in .NET series. See the last one here. This time, I’m going to present a framework for doing dynamic interception. Mind you, this is proof of concept code, it is not ready for production usage, although it can do some interesting things! This is going to be a long post, bear with me!

Core Concepts and Types

As I mentioned on the second post, there are essentially four dynamic interception techniques for .NET:

  • Virtual method interception
  • Interface interception
  • Transparent proxy interception
  • Context-bound object interception

I’m going to introduce another one, interception using dynamics, at the end of this post, I think it has some merits of its own.

The interceptors are organized into two groups:

  • Instance interceptors: interface interceptor, dynamic interceptor, context-bound object interceptor, transparent proxy interceptor
  • Type interceptors: virtual method interceptor

An instance interceptor is one that takes an existing object and intercepts calls made to its methods. A type interceptor, on the other hand, generates a type deriving from a given one that, when instantiated, will have the interception hooks that we chose to add to it.

The interception hooks mean that we can intercept a method call – and remember that properties are actually methods – and execute custom code before, after or instead of the intercepted method. An interception hook for an instance interceptor is an instance of a class that implements some interface, and for a type interceptor, it is a type that also implements that specific interface.

Let’s see some basic interfaces, first, the IInterceptor:

public interface IInterceptor
{
}

Not much to it, as you can see, I only use it as the base for both the instance and type interceptor contracts. Next, the IInstanceInterceptor, that is, the contract for an instance interceptor:

public interface IInstanceInterceptor : IInterceptor
{
object Intercept(object instance, Type typeToIntercept, IInterceptionHandler handler);

bool CanIntercept(object instance);
}

Only two methods, nothing too complex:

  • CanIntercept returns true if the instance can be intercepted, by the particular interceptor
  • Intercept receives the instance to intercept, an optional interface type and returns a proxy to the object being intercepted

I would also like to introduce now the IInterceptionHandler interface, which represents our interception hook:

public interface IInterceptionHandler
{
void Invoke(InterceptionArgs arg);
}

Only one method, Invoke, which is called when an interception is under way. Its InterceptionArgs contains the method to be intercepted, the actual instance where the method is being invoked, any method arguments and the desired return value:

[Serializable]
public sealed class InterceptionArgs : EventArgs
{
private object result;

public InterceptionArgs(object instance, MethodInfo method, params object [] arguments)
{
this.Instance = instance;
this.Method = method;
this.Arguments = arguments;
}

public void Proceed()
{
this.Result = this.Method.Invoke(this.Instance, this.Arguments);
}

public object Instance
{
get;
private set;
}

public MethodInfo Method
{
get;
private set;
}

public object [] Arguments
{
get;
private set;
}

public bool Handled
{
get;
set;
}

public object Result
{
get
{
return (this.result);
}
set
{
this.result = value;
this.Handled = true;
}
}
}

Noteworthy:

  • Method is, of course, the method being intercepted, which may well be either the setter or the getter of a property
  • Result will contain the result of the execution, if the intercepted method is not void
  • Arguments are the arguments being passed to the intercepted method
  • Instance is the actual instance on which the method was called
  • Handled is a flag that is set by the IInterceptionHandler’s Invoke method to tell the framework that we intercepted the normal course of the call
  • The Proceed method, if called, will cause the intercepted call to execute as if it hadn’t been intercepted

The ITypeInterceptor type, the contract for type interceptors:

public interface ITypeInterceptor : IInterceptor
{
Type Intercept(Type typeToIntercept, Type interceptionType);

bool CanIntercept(Type typeToIntercept);
}

Pretty similar to IInstanceInterceptor, but:

  • CanIntercept takes a Type instead of an instance
  • Intercept also takes the Type to intercept and the interception type (implementing IInterceptionHandler) and returns another Type, which should be a subclass of the Type to intercept

And, finally, the interface that is going to be implemented by generated (proxified) types, IInterceptionProxy:

public interface IInterceptionProxy
{
IInterceptor Interceptor
{
get;
}
}

Now let’s see how we implement the actual interceptors.

Virtual Method Interceptor

A virtual method interceptor is a type interceptor, it needs to generate dynamically a class that inherits from the passed type and, for all of its virtual methods that are marked for interception, override them in this dynamic class, adding hooks for the interception aspect.

There are basically two APIs in classic .NET for generating code at runtime:

Recently, we have another option: Roslyn. But I won’t talk about it here, definitely a topic for a future series of posts on its own.

For this example, I am going to use CodeDOM. The VirtualMethodInterceptor class looks like this:

public sealed class VirtualMethodInterceptor : ITypeInterceptor
{
private readonly InterceptedTypeGenerator generator;

public VirtualMethodInterceptor(InterceptedTypeGenerator generator)
{
this.generator = generator;
}

public VirtualMethodInterceptor() : this(CodeDOMInterceptedTypeGenerator.Instance)
{

}

private Type CreateType(Type typeToIntercept, Type handlerType)
{
return (this.generator.Generate(this, typeToIntercept, handlerType));
}

public Type Intercept(Type typeToIntercept, Type handlerType)
{
if (typeToIntercept == null)
{
throw (new ArgumentNullException("typeToIntercept"));
}

if (handlerType == null)
{
throw (new ArgumentNullException("handlerType"));
}

if (this.CanIntercept(typeToIntercept) == false)
{
throw (new ArgumentException("typeToIntercept"));
}

if (typeof(IInterceptionHandler).IsAssignableFrom(handlerType) == false)
{
throw (new ArgumentException("handlerType"));
}

if (handlerType.IsPublic == false)
{
throw (new ArgumentException("handlerType"));
}

if ((handlerType.IsAbstract == true) || (handlerType.IsInterface == true))
{
throw (new ArgumentException("handlerType"));
}

if (handlerType.GetConstructor(Type.EmptyTypes) == null)
{
throw (new ArgumentException("handlerType"));
}

return (this.CreateType(typeToIntercept, handlerType));
}

public bool CanIntercept(Type typeToIntercept)
{
return ((typeToIntercept.IsInterface == false) && (typeToIntercept.IsSealed == false));
}
}

The biggest part of the work is done, however, by a type generator. We have a base class for it, InterceptedTypeGenerator:

public abstract class InterceptedTypeGenerator
{
public abstract Type Generate(IInterceptor interceptor, Type baseType, Type handlerType, params Type [] additionalInterfaceTypes);
}

Its contract specifies the base type (that is going to be subclassed), any additional interfaces and an interception handler type, which needs to implement IInterceptionHandler and have a public parameterless constructor.

And here is a concrete implementation using CodeDOM, CodeDOMInterceptedTypeGenerator:

internal class CodeDOMInterceptedTypeGenerator : InterceptedTypeGenerator
{
public static readonly InterceptedTypeGenerator Instance = new CodeDOMInterceptedTypeGenerator();

private static readonly CodeDomProvider provider = new CSharpCodeProvider();
private static readonly CodeGeneratorOptions options = new CodeGeneratorOptions() { BracingStyle = "C" };
private static readonly CodeTypeReference proxyTypeReference = new CodeTypeReference(typeof(IInterceptionProxy));
private static readonly CodeTypeReference interceptorTypeReference = new CodeTypeReference(typeof(IInterceptor));
private static readonly CodeTypeReference handlerTypeReference = new CodeTypeReference(typeof(IInterceptionHandler));
private static readonly Assembly proxyAssembly = typeof(IInterceptionProxy).Assembly;
private static readonly Type interfaceProxyType = typeof(InterfaceProxy);

protected virtual void GenerateConstructors(CodeTypeDeclaration targetClass, Type baseType, IEnumerable<ConstructorInfo> constructors)
{
foreach (var constructor in constructors)
{
var c = new CodeConstructor();
targetClass.Members.Add(c);

c.Attributes = MemberAttributes.Final | MemberAttributes.Override;

foreach (var parameter in constructor.GetParameters())
{
c.Parameters.Add(new CodeParameterDeclarationExpression(parameter.ParameterType, parameter.Name));
}

if (baseType == interfaceProxyType)
{
c.Attributes |= MemberAttributes.Public;
}
else
{
if ((constructor.Attributes & MethodAttributes.Public) == MethodAttributes.Public)
{
c.Attributes |= MemberAttributes.Public;
}
else if ((constructor.Attributes & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem)
{
c.Attributes |= MemberAttributes.FamilyOrAssembly;
}
else if ((constructor.Attributes & MethodAttributes.Family) == MethodAttributes.Family)
{
c.Attributes |= MemberAttributes.Family;
}
else if ((constructor.Attributes & MethodAttributes.FamANDAssem) == MethodAttributes.FamANDAssem)
{
c.Attributes |= MemberAttributes.FamilyAndAssembly;
}
}

foreach (var p in constructor.GetParameters())
{
c.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression(p.Name));
}
}
}

protected virtual void GenerateMethods(CodeTypeDeclaration targetClass, Type baseType, IEnumerable<MethodInfo> methods)
{
if (methods.Any() == true)
{
var finalizeMethod = methods.First().DeclaringType.GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance);

foreach (var method in methods)
{
if (method == finalizeMethod)
{
continue;
}

if (method.IsSpecialName == true)
{
continue;
}

var m = new CodeMemberMethod();
m.Name = method.Name;
m.ReturnType = new CodeTypeReference(method.ReturnType);

if (baseType != interfaceProxyType)
{
m.Attributes = MemberAttributes.Override;
}

targetClass.Members.Add(m);

foreach (var parameter in method.GetParameters())
{
m.Parameters.Add(new CodeParameterDeclarationExpression(parameter.ParameterType, parameter.Name));
}

if ((method.Attributes & MethodAttributes.Public) == MethodAttributes.Public)
{
m.Attributes |= MemberAttributes.Public;
}
else if ((method.Attributes & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem)
{
m.Attributes |= MemberAttributes.FamilyOrAssembly;
}
else if ((method.Attributes & MethodAttributes.Family) == MethodAttributes.Family)
{
m.Attributes |= MemberAttributes.Family;
}
else if ((method.Attributes & MethodAttributes.FamANDAssem) == MethodAttributes.FamANDAssem)
{
m.Attributes |= MemberAttributes.FamilyAndAssembly;
}

if (baseType == interfaceProxyType)
{
m.Attributes = MemberAttributes.Public | MemberAttributes.Final;
}

var currentMethod = new CodeVariableDeclarationStatement(typeof(MethodInfo), "currentMethod", new CodeCastExpression(typeof(MethodInfo), new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(MethodBase)), "GetCurrentMethod"))));
var getType = new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "instance"), "GetType");
var getMethod = new CodeMethodInvokeExpression(getType, "GetMethod", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("currentMethod"), "Name"));
var originalMethod = new CodeVariableDeclarationStatement(typeof(MethodInfo), "originalMethod", getMethod);

m.Statements.Add(currentMethod);
m.Statements.Add(originalMethod);

var ps = new CodeExpression[] { new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "instance"), new CodeVariableReferenceExpression("originalMethod") }.Concat(method.GetParameters().Select(x => new CodeVariableReferenceExpression(x.Name))).ToArray();
var arg = new CodeVariableDeclarationStatement(typeof(InterceptionArgs), "args", new CodeObjectCreateExpression(typeof(InterceptionArgs), ps));

m.Statements.Add(arg);

var handler = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "handler"), "Invoke"), new CodeVariableReferenceExpression("args"));
m.Statements.Add(handler);

var comparison = new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("args"), "Handled"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(method.ReturnType != typeof(void)));
CodeConditionStatement @if = null;

if (method.ReturnType != typeof(void))
{
if (baseType != interfaceProxyType)
{
@if = new CodeConditionStatement(comparison, new CodeMethodReturnStatement(new CodeCastExpression(method.ReturnType, new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("args"), "Result"))));

m.Statements.Add(@if);
m.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), method.Name, method.GetParameters().Select(x => new CodeArgumentReferenceExpression(x.Name)).ToArray())));
}
else
{
@if = new CodeConditionStatement(comparison, new CodeMethodReturnStatement(new CodeCastExpression(method.ReturnType, new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("args"), "Result"))));

m.Statements.Add(@if);
m.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeCastExpression(method.DeclaringType, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "instance")), m.Name), method.GetParameters().Select(x => new CodeArgumentReferenceExpression(x.Name)).ToArray())));
}
}
else
{
if (baseType != interfaceProxyType)
{
@if = new CodeConditionStatement(comparison, new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), method.Name, method.GetParameters().Select(x => new CodeArgumentReferenceExpression(x.Name)).ToArray())));

m.Statements.Add(@if);
}
else
{
@if = new CodeConditionStatement(comparison, new CodeMethodReturnStatement(new CodeCastExpression(method.ReturnType, new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("args"), "Result"))));

m.Statements.Add(@if);
m.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeCastExpression(method.DeclaringType, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "instance")), m.Name), method.GetParameters().Select(x => new CodeArgumentReferenceExpression(x.Name)).ToArray())));
}
}
}
}
}

protected virtual void GenerateProperties(CodeTypeDeclaration targetClass, Type baseType, IEnumerable<PropertyInfo> properties)
{
var interceptorProperty = new CodeMemberProperty();
interceptorProperty.Name = "Interceptor";
interceptorProperty.Type = interceptorTypeReference;
interceptorProperty.Attributes |= MemberAttributes.Private;
interceptorProperty.PrivateImplementationType = proxyTypeReference;
interceptorProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "interceptor")));
targetClass.Members.Add(interceptorProperty);

foreach (var property in properties)
{
var p = new CodeMemberProperty();
p.Name = property.Name;
p.Type = new CodeTypeReference(property.PropertyType);

if (baseType != interfaceProxyType)
{
p.Attributes = MemberAttributes.Override;
}

targetClass.Members.Add(p);

if (property.CanRead == true)
{
p.HasGet = true;

if ((property.GetMethod.Attributes & MethodAttributes.Public) == MethodAttributes.Public)
{
p.Attributes |= MemberAttributes.Public;
}
else if ((property.GetMethod.Attributes & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem)
{
p.Attributes |= MemberAttributes.FamilyOrAssembly;
}
else if ((property.GetMethod.Attributes & MethodAttributes.Family) == MethodAttributes.Family)
{
p.Attributes |= MemberAttributes.Family;
}
else if ((property.GetMethod.Attributes & MethodAttributes.FamANDAssem) == MethodAttributes.FamANDAssem)
{
p.Attributes |= MemberAttributes.FamilyAndAssembly;
}

if (baseType == interfaceProxyType)
{
p.Attributes = MemberAttributes.Public | MemberAttributes.Final;
}

var currentMethod = new CodeVariableDeclarationStatement(typeof(MethodInfo), "currentMethod", new CodeCastExpression(typeof(MethodInfo), new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(MethodBase)), "GetCurrentMethod"))));
var getType = new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "instance"), "GetType");
var getMethod = new CodeMethodInvokeExpression(getType, "GetMethod", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("currentMethod"), "Name"));
var originalMethod = new CodeVariableDeclarationStatement(typeof(MethodInfo), "originalMethod", getMethod);

p.GetStatements.Add(currentMethod);
p.GetStatements.Add(originalMethod);

var ps = new CodeExpression[] { new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "instance"), new CodeVariableReferenceExpression("originalMethod") };
var arg = new CodeVariableDeclarationStatement(typeof(InterceptionArgs), "args", new CodeObjectCreateExpression(typeof(InterceptionArgs), ps));

p.GetStatements.Add(arg);

var handler = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "handler"), "Invoke"), new CodeVariableReferenceExpression("args"));
p.GetStatements.Add(handler);

var comparison = new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("args"), "Handled"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true));
var @if = new CodeConditionStatement(comparison, new CodeMethodReturnStatement(new CodeCastExpression(property.PropertyType, new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("args"), "Result"))));

p.GetStatements.Add(@if);

if (baseType != interfaceProxyType)
{
p.GetStatements.Add(new CodeMethodReturnStatement(new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(), property.Name)));
}
else
{
p.GetStatements.Add(new CodeMethodReturnStatement(new CodePropertyReferenceExpression(new CodeCastExpression(property.DeclaringType, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "instance")), property.Name)));
}
}

if (property.CanWrite == true)
{
p.HasSet = true;

var ps = new CodeExpression[]
{
new CodeThisReferenceExpression(),
new CodeCastExpression(typeof(MethodInfo), new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(MethodBase)), "GetCurrentMethod"))),
new CodeVariableReferenceExpression("value")
};

var arg = new CodeVariableDeclarationStatement(typeof(InterceptionArgs), "args", new CodeObjectCreateExpression(typeof(InterceptionArgs), ps));

p.SetStatements.Add(arg);

var handler = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "handler"), "Invoke"), new CodeVariableReferenceExpression("args"));
p.SetStatements.Add(handler);

var comparison = new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("args"), "Handled"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true));
var @if = new CodeConditionStatement(comparison, new CodeMethodReturnStatement());

p.SetStatements.Add(@if);

if (baseType != interfaceProxyType)
{
p.SetStatements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(), property.Name), new CodeVariableReferenceExpression("value")));
}
else
{
p.SetStatements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeCastExpression(property.DeclaringType, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "instance")), property.Name), new CodeVariableReferenceExpression("value")));
}
}
}
}

protected virtual void GenerateFields(CodeTypeDeclaration targetClass, Type baseType, Type handlerType, Type interceptorType)
{
if (handlerType != null)
{
var handlerField = new CodeMemberField();
handlerField.Attributes = MemberAttributes.FamilyOrAssembly;
handlerField.Name = "handler";
handlerField.Type = handlerTypeReference;
handlerField.InitExpression = (handlerType != null) ? new CodeObjectCreateExpression(handlerType) : null;
targetClass.Members.Add(handlerField);
}

var interceptorField = new CodeMemberField();
interceptorField.Attributes = MemberAttributes.FamilyOrAssembly;
interceptorField.Name = "interceptor";
interceptorField.Type = interceptorTypeReference;
interceptorField.InitExpression = (interceptorType != null) ? new CodeObjectCreateExpression(interceptorType) : null;
targetClass.Members.Add(interceptorField);
}

protected virtual void AddReferences(CompilerParameters parameters, Type baseType, Type handlerType, Type interceptorType, Type [] additionalInterfaceTypes)
{
parameters.ReferencedAssemblies.Add(string.Concat(proxyAssembly.GetName().Name, Path.GetExtension(proxyAssembly.CodeBase)));
parameters.ReferencedAssemblies.Add(string.Concat(baseType.Assembly.GetName().Name, Path.GetExtension(baseType.Assembly.CodeBase)));

if (handlerType != null)
{
parameters.ReferencedAssemblies.Add(string.Concat(handlerType.Assembly.GetName().Name, Path.GetExtension(handlerType.Assembly.CodeBase)));
}

if (interceptorType != null)
{
parameters.ReferencedAssemblies.Add(string.Concat(interceptorType.Assembly.GetName().Name, Path.GetExtension(interceptorType.Assembly.CodeBase)));
}

foreach (var additionalInterfaceType in additionalInterfaceTypes)
{
parameters.ReferencedAssemblies.Add(string.Concat(additionalInterfaceType.Assembly.GetName().Name, Path.GetExtension(additionalInterfaceType.Assembly.CodeBase)));
}
}

protected virtual IEnumerable<PropertyInfo> GetProperties(Type baseType, Type[] additionalInterfaceTypes)
{
if (baseType != interfaceProxyType)
{
return (baseType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(x => ((x.CanRead == true) && (x.GetMethod.IsVirtual == true)) || ((x.CanWrite == true) && (x.SetMethod.IsVirtual == true))).Concat(additionalInterfaceTypes.SelectMany(x => x.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(y => ((y.CanRead == true) && (y.GetMethod.IsVirtual == true)) || ((y.CanWrite == true) && (y.SetMethod.IsVirtual == true))))).Distinct().ToList());
}
else
{
return (additionalInterfaceTypes.SelectMany(x => x.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(y => ((y.CanRead == true) && (y.GetMethod.IsVirtual == true)) || ((y.CanWrite == true) && (y.SetMethod.IsVirtual == true)))).Distinct().ToList());
}
}

protected virtual IEnumerable<MethodInfo> GetMethods(Type baseType, Type [] additionalInterfaceTypes)
{
if (baseType != interfaceProxyType)
{
return (baseType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(x => x.IsFinal == false && (x.IsVirtual == true || x.IsAbstract == true)).Concat(additionalInterfaceTypes.SelectMany(x => x.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(y => y.IsVirtual == true))).Distinct().ToList());
}
else
{
return (additionalInterfaceTypes.SelectMany(x => x.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(y => y.IsFinal == false && (y.IsVirtual == true || y.IsAbstract == true))).Distinct().ToList());
}
}

protected virtual IEnumerable<ConstructorInfo> GetConstructors(Type baseType)
{
return (baseType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
}

public override Type Generate(IInterceptor interceptor, Type baseType, Type handlerType, params Type[] additionalInterfaceTypes)
{
var properties = this.GetProperties(baseType, additionalInterfaceTypes);
var methods = this.GetMethods(baseType, additionalInterfaceTypes);
var constructors = this.GetConstructors(baseType);

var targetClass = new CodeTypeDeclaration(string.Concat(baseType.Name, "_Dynamic"));
targetClass.IsClass = baseType.IsClass;
targetClass.TypeAttributes = TypeAttributes.Sealed | TypeAttributes.Serializable;
targetClass.BaseTypes.Add((baseType.IsInterface == false) ? baseType : typeof(object));
targetClass.BaseTypes.Add(proxyTypeReference.BaseType);

foreach (var additionalInterfaceType in additionalInterfaceTypes)
{
targetClass.BaseTypes.Add(additionalInterfaceType);
}

var samples = new CodeNamespace(baseType.Namespace);
samples.Imports.Add(new CodeNamespaceImport(typeof(string).Namespace));
samples.Types.Add(targetClass);

var targetUnit = new CodeCompileUnit();
targetUnit.Namespaces.Add(samples);

this.GenerateFields(targetClass, baseType, handlerType, (interceptor != null) ? interceptor.GetType() : null);

this.GenerateConstructors(targetClass, baseType, constructors);

this.GenerateMethods(targetClass, baseType, methods);

this.GenerateProperties(targetClass, baseType, properties);

var builder = new StringBuilder();

using (var sourceWriter = new StringWriter(builder))
{
provider.GenerateCodeFromCompileUnit(targetUnit, sourceWriter, options);
}

var parameters = new CompilerParameters() { GenerateInMemory = true };

this.AddReferences(parameters, baseType, handlerType, (interceptor != null) ? interceptor.GetType() : null, additionalInterfaceTypes);

var results = provider.CompileAssemblyFromDom(parameters, targetUnit);

if (results.Errors.HasErrors == true)
{
throw new InvalidOperationException(string.Join(Environment.NewLine, results.Errors.OfType<object>()));
}

return (results.CompiledAssembly.GetTypes().First());
}
}

Granted, this one is a bit complex, as it needs to generate a whole type dynamically, including constructors to match the base type, overrides for virtual method and properties, and it needs to have them call the interception handler instance. The generated type will also implement the IInterceptionProxy interface, which exposes a Interceptor property, from which you can at runtime access the interceptor. If you are not used to working with the code DOM, have a look at it, you might find it instructive! Winking smile

ClassDiagram1

In the end, here is the code to use it:

public class MyInterceptedType
{
public virtual int Property { get; set; }
public virtual void Method() { /* ... */ }
}

var interceptor = new VirtualMethodInterceptor();
var myProxyType = interceptor.Intercept(type, typeof(MyInterceptionHandler));
var myProxy = Activator.CreateInstance(myProxyType) as MyInterceptedType;
myProxy.Method(); //will get intercepted

The only care that you need to take is to only intercept non-virtual types, with public constructors. Also, the interception handler type must have a public parameterless constructor.

Interface Interception

This one is an instance interceptor. The instance to intercept must implement a given interface. Here is the code of InterfaceInterceptor:

public sealed class InterfaceInterceptor : IInstanceInterceptor
{
private readonly InterceptedTypeGenerator generator;

public InterfaceInterceptor(InterceptedTypeGenerator generator)
{
this.generator = generator;
}

public InterfaceInterceptor() : this(CodeDOMInterceptedTypeGenerator.Instance)
{
}

public object Intercept(object instance, Type typeToIntercept, IInterceptionHandler handler)
{
if (instance == null)
{
throw (new ArgumentNullException("instance"));
}

if (typeToIntercept == null)
{
throw (new ArgumentNullException("typeToIntercept"));
}

if (handler == null)
{
throw (new ArgumentNullException("handler"));
}

if (typeToIntercept.IsInstanceOfType(instance) == false)
{
throw (new ArgumentNullException("instance"));
}

if (typeToIntercept.IsInterface == false)
{
throw (new ArgumentNullException("typeToIntercept"));
}

if (this.CanIntercept(instance) == false)
{
throw (new ArgumentNullException("instance"));
}

var interfaceProxy = this.generator.Generate(this, typeof(InterfaceProxy), null, typeToIntercept);

var newInstance = Activator.CreateInstance(interfaceProxy, this, handler, instance);

return (newInstance);
}

public bool CanIntercept(object instance)
{
return (instance.GetType().GetInterfaces().Length != 0);
}
}

You can see that it also needs to generate code at runtime, therefore it uses the same types InterceptedTypeGenerator and CodeDOMInterceptedTypeGenerator shown earlier. This time, the generated proxy implements the interface to intercept and is a subclass of InterfaceProxy:

public abstract class InterfaceProxy
{
protected readonly object instance;
protected readonly IInterceptor interceptor;
protected readonly IInterceptionHandler handler;

protected InterfaceProxy(IInterceptor interceptor, IInterceptionHandler handler, object instance)
{
this.instance = instance;
this.interceptor = interceptor;
this.handler = handler;
}
}

We use it like this:

public interface IMyInterceptedType
{
int Property { get; set; }
void Method();
}

public class MyInterceptedType : IMyInterceptedType
{
public int Property { get; set; }
public void Method() { /* ... */ }
}

var instance = new MyInterceptedType();
var interceptor = new InterfaceInterceptor();
var myProxy = interceptor.Intercept(instance, typeof(IMyInterceptedType), new MyInterceptionHandler()) as IMyInterceptedType;
myProxy.Method(); //will get intercepted

As you can see, all the intercepted type needs is to implement one interface, it’s this interface that can actually be intercepted, and this is the second parameter to the https://msdn.microsoft.com/en-us/library/ms731082(v=vs.110).aspxmethod.

ClassDiagram2

Transparent Proxy Interceptor

This one is the technique that WCF and .NET Remoting use to communicate to a remote system.

The TransparentProxyInterceptor is an instance interceptor:

public sealed class TransparentProxyInterceptor : IInstanceInterceptor
{
public static readonly IInstanceInterceptor Instance = new TransparentProxyInterceptor();

public object Intercept(object instance, Type typeToIntercept, IInterceptionHandler handler)
{
if (instance == null)
{
throw (new ArgumentNullException("instance"));
}

if (typeToIntercept == null)
{
throw (new ArgumentNullException("typeToIntercept"));
}

if (handler == null)
{
throw (new ArgumentNullException("handler"));
}

if (this.CanIntercept(instance) == false)
{
throw (new ArgumentException("instance"));
}

if (typeToIntercept.IsInstanceOfType(instance) == false)
{
throw (new ArgumentException("typeToIntercept"));
}

var proxy = new TransparentProxy(this, instance, typeToIntercept, handler);

return (proxy.GetTransparentProxy());
}

public bool CanIntercept(object instance)
{
return ((instance is MarshalByRefObject) || (instance.GetType().GetInterfaces().Length != 0));
}
}

Here, we don’t generate any code, we just leverage MarshalByRefObject and RealProxy, which do all the magic. We need a type that extends RealProxy and adds our own IInterceptionProxy:

internal sealed class TransparentProxy : RealProxy, IRemotingTypeInfo, IInterceptionProxy
{
private readonly object instance;
private readonly IInterceptionHandler handler;
private readonly TransparentProxyInterceptor interceptor;

public TransparentProxy(TransparentProxyInterceptor interceptor, object instance, Type typeToIntercept, IInterceptionHandler handler) : base(typeToIntercept)
{
this.instance = instance;
this.handler = handler;
this.interceptor = interceptor;
}

public override IMessage Invoke(IMessage msg)
{
ReturnMessage responseMessage;
object response = null;
Exception caughtException = null;

try
{
var methodName = msg.Properties["__MethodName"] as string;
var parameterTypes = msg.Properties["__MethodSignature"] as Type[];
var parameters = msg.Properties["__Args"] as object[];
var typeName = msg.Properties["__TypeName"] as string;
var method = this.instance.GetType().GetMethod(methodName, parameterTypes);

if (method == null)
{
if (methodName.StartsWith("get_") == true)
{
var property = this.instance.GetType().GetProperty(methodName.Substring(4), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

if (property != null)
{
method = property.GetGetMethod();
}
else
{
if ((methodName == "get_Interceptor") && (typeName == typeof(IInterceptionProxy).AssemblyQualifiedName))
{
return (new ReturnMessage(this.interceptor, null, 0, null, msg as IMethodCallMessage));
}
}
}
}

var args = new InterceptionArgs(this.instance, method, parameters);

this.handler.Invoke(args);

if (args.Handled == false)
{
args.Proceed();
}

response = args.Result;
}
catch (Exception ex)
{
caughtException = ex;
}

var message = msg as IMethodCallMessage;

if (caughtException == null)
{
responseMessage = new ReturnMessage(response, null, 0, null, message);
}
else
{
responseMessage = new ReturnMessage(caughtException, message);
}

return (responseMessage);
}

bool IRemotingTypeInfo.CanCastTo(Type fromType, object o)
{
return (fromType == typeof(IInterceptionProxy));
}

string IRemotingTypeInfo.TypeName
{
get;
set;
}

public IInterceptor Interceptor
{
get { return this.interceptor; }
}
}

Using TransparentProxyInterceptor we can only intercept types that either inherit from MarshalByRefObject or implement some interface, in which case, we can only intercept methods and properties coming from that interface.

Here’s how we would use it with any type (not inheriting from MarshalByRefObject) that exposes an interface:

public interface IMyInterceptedType
{
int Property { get; set; }
void Method();
}

public class MyInterceptedType : IMyInterceptedType
{
public int Property { get; set; }
public void Method() { /* ... */ }
}

var instance = new MyInterceptedType();
var interceptor = new TransparentProxyInterceptor();
var canIntercept = interceptor.CanIntercept(instance);
var myProxy = interceptor.Intercept(instance, typeof(IMyInterceptedType), new MyInterceptionHandler()) as IMyInterceptedType;
var proxy = myProxy as IInterceptionProxy;
var otherInterceptor = proxy.Interceptor;
myProxy.Method(); //will get intercepted

Again, all it takes is an interface to intercept.

Context Bound Object Interceptor

Since its early days, .NET introduced an interception mechanism that doesn’t need any coding. The problem is that it requires inheriting from a particular base class (ContextBoundObject) plus adding an attribute to it (ContextAttribute). I include this technique here for completeness, since it is usually not that useful.

The ContextBoundInterceptor looks like this:

public sealed class ContextBoundObjectInterceptor : IInstanceInterceptor
{
public static readonly IInstanceInterceptor Instance = new ContextBoundObjectInterceptor();

internal static readonly ConcurrentDictionary<ContextBoundObject, IInterceptionHandler> interceptors = new ConcurrentDictionary<ContextBoundObject, IInterceptionHandler>();

public object Intercept(object instance, Type typeToIntercept, IInterceptionHandler handler)
{
if (!(instance is ContextBoundObject))
{
throw new ArgumentException("Instance is not a ContextBoundObject.", "instance");
}

interceptors[instance as ContextBoundObject] = handler;

return (instance);
}

public bool CanIntercept(object instance)
{
return ((instance is ContextBoundObject) && (Attribute.IsDefined(instance.GetType(), typeof(InterceptionContextAttribute))));
}

public static IInterceptionHandler GetInterceptor(ContextBoundObject instance)
{
foreach (var @int in interceptors)
{
if (@int.Key == instance)
{
return @int.Value;
}
}

return null;
}
}

We need to use a trick here to associate an interceptor with an intercepted instance, in the form of a static dictionary. In order to make this work, we also need the InterceptionContextAttribute:

[Serializable]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class InterceptionContextAttribute : ContextAttribute
{
public InterceptionContextAttribute() : base("InterceptionContext")
{
}

public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
{
ctorMsg.ContextProperties.Add(new InterceptionProperty());
base.GetPropertiesForNewContext(ctorMsg);
}

public override bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
{
var p = ctx.GetProperty(InterceptionProperty.InterceptionPropertyName) as InterceptionProperty;
return (p != null);
}

public override bool IsNewContextOK(Context newCtx)
{
var p = newCtx.GetProperty(InterceptionProperty.InterceptionPropertyName) as InterceptionProperty;
return (p != null);
}
}

And the InterceptionProperty:

internal sealed class InterceptionProperty : IContextProperty, IContributeObjectSink
{
internal static readonly string InterceptionPropertyName = "Interception";

public string Name
{
get
{
return InterceptionPropertyName;
}
}

public bool IsNewContextOK(Context newCtx)
{
var p = newCtx.GetProperty(this.Name) as InterceptionProperty;
return p != null;
}

public void Freeze(Context newContext)
{
}

public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
return new InterceptionMessageSink(obj as ContextBoundObject, nextSink);
}
}

Much more work that it deserves, I’d say. Anyway, here’s a sample usage:

public interface IMyInterceptedType
{
int Property { get; set; }
void Method();
}

[InterceptionContext]
public class MyInterceptedType : ContextBoundObject, IMyInterceptedType
{
public int Property { get; set; }
public void Method() { /* ... */ }
}

var instance = new MyInterceptedType();
var interceptor = new ContextBoundObjectInterceptor();
var myProxy = interceptor.Intercept(instance, null, new MyInterceptionHandler()) as IMyInterceptedType;
myProxy.Method(); //will get intercepted

As I said, this technique is only listed here for completeness’ sake, I don’t expect you to be using it much.

Dynamic Interceptor

Final technique, this time, we will be making use of the dynamic functionality introduced in .NET 4.

First, the DynamicInterceptor class, another instance interceptor:

public sealed class DynamicInterceptor : IInstanceInterceptor
{
public static readonly IInstanceInterceptor Instance = new DynamicInterceptor();

public object Intercept(object instance, Type typeToIntercept, IInterceptionHandler handler)
{
return new DynamicProxy(this, instance, handler);
}

public bool CanIntercept(object instance)
{
return true;
}
}

Simple, right? And here is the DynamicProxy:

internal sealed class DynamicProxy : DynamicObject, IInterceptionProxy
{
private readonly IInterceptionHandler handler;
private readonly object target;

public DynamicProxy(IInterceptor interceptor, object target, IInterceptionHandler handler)
{
if (interceptor == null)
{
throw new ArgumentNullException("target");
}

if (target == null)
{
throw new ArgumentNullException("target");
}

if (handler == null)
{
throw new ArgumentNullException("handler");
}

this.Interceptor = interceptor;
this.target = target;
this.handler = handler;
}

public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
var method = this.target.GetType().GetMethod(binder.Name);
var arg = new InterceptionArgs(this.target, method, args);

this.handler.Invoke(arg);

if (arg.Handled == true)
{
result = arg.Result;
}
else
{
result = method.Invoke(this.target, args);
}

return true;
}

public IInterceptor Interceptor { get; private set; }
}

This one inherits from DynamicObject, which allows us to find properties and methods at runtime.

Finally, its usage:

public class MyInterceptedType
{
public int Property { get; set; }
public void Method() { /* ... */ }
}

var instance = new MyInterceptedType();
var interceptor = new DynamicInterceptor();
//here: using dynamic instead of MyInterceptedType!
dynamic myProxy = interceptor.Intercept(instance, null, new MyInterceptionHandler());
myProxy.Method(); //will get intercepted

No constraints whatsoever in what you can intercept, you need only to remember to declare your proxy as dynamic instead of an actual type.

Interception Handlers

Looks cool, right? What about interception handlers – the parameter that you pass to one of the Intercept methods? Well, it is agnostic as to what interception technique you use and just needs to implement IInterceptionHandler. Its Invoke method is called with a parameter that contains all the information that you need. From there you can do some stuff before calling letting the normal flow proceed, change the arguments to the intercepted method, change the return value (in the case of non-void intercepted methods), do stuff after calling the intercepted method or not call it at all:

public void Invoke(InterceptionArgs arg)
{
arg.Parameters[1] = 120; //changed the original parameters

Console.WriteLine("Before execution");

arg.Proceed(); //call the intercepted method

Console.WriteLine("After execution");

arg.Result = "some result"; //changed the return value

arg.Handled = true; //signal to other interceptors that it has been handled
}

Here is a simple implementation that retries a method call a couple of times in case it throws an exception:

public sealed class RetriesInterceptionHandler : IInterceptionHandler
{
public RetriesInterceptionHandler()
{
this.Retries = 3;
this.Delay = TimeSpan.FromSeconds(5);
}

public int Retries { get; set; }
public TimeSpan Delay { get; set; }

public void Invoke(InterceptionArgs arg)
{
for (var i = 0; i < this.Retries; i++)
{
try
{
arg.Proceed();
break;
}
catch
{
if (i != this.Retries - 1)
{
Thread.Sleep(this.Delay);
}
else
{
throw;
}
}
}
}
}

When it is asked to intercept a method call it loops a number of times, tries to call the default implementation, and, in the event of an exception, sleeps for a while and tries again. If it reached the maximum number of retries, it just throws the caught exception.

Another common scenario is to use attributes as Aspects. We just need to implement an interception handler that looks at interception attributes:

public sealed class AttributesInterceptionHandler : IInterceptionHandler
{
public static readonly IInterceptionHandler Instance = new AttributesInterceptionHandler();

public void Invoke(InterceptionArgs arg)
{
var attrs = arg.Method.GetCustomAttributes(true).OfType<InterceptionAttribute>().OrderBy(x => x.Order).Cast<IInterceptionHandler>();

foreach (var attr in attrs)
{
attr.Invoke(arg);
}
}
}

Where an InterceptionAttribute base class could be implemented as this:

[Serializable]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public abstract class InterceptionAttribute : Attribute, IInterceptionHandler
{
public int Order { get; set; }

public abstract void Invoke(InterceptionArgs arg);
}

You can specify an order by which you want interception attributes to execute.

Yet another technique, using a registry to associate the methods to intercept with their desired handler:

public sealed class RegistryInterceptionHandler : IInterceptionHandler
{
private readonly Dictionary<MethodInfo, IInterceptionHandler> handlers = new Dictionary<MethodInfo, IInterceptionHandler>();

public RegistryInterceptionHandler Register(Type type, string methodName, IInterceptionHandler handler)
{
foreach (var method in type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public))
{
this.Register(method, handler);
}

return this;
}

public RegistryInterceptionHandler Register(MethodInfo method, IInterceptionHandler handler)
{
if (method == null)
{
throw new ArgumentNullException("method");
}

if (handler == null)
{
throw new ArgumentNullException("handler");
}

this.handlers[method] = handler;

return this;
}

private RegistryInterceptionHandler RegisterExpressionMethod(Expression expression, IInterceptionHandler handler)
{
if (expression is MethodCallExpression)
{
return this.Register((expression as MethodCallExpression).Method, handler);
}
else if (expression is UnaryExpression)
{
if ((expression as UnaryExpression).Operand is MethodCallExpression)
{
return this.Register(((expression as UnaryExpression).Operand as MethodCallExpression).Method, handler);
}
}
else if (expression is MemberExpression)
{
if ((expression as MemberExpression).Member is PropertyInfo)
{
this.Register(((expression as MemberExpression).Member as PropertyInfo).GetMethod, handler);
return this.Register(((expression as MemberExpression).Member as PropertyInfo).SetMethod, handler);
}
}

throw new ArgumentException("Expression is not a method call", "method");
}

public RegistryInterceptionHandler Register<T>(Expression<Func<T, object>> method, IInterceptionHandler handler)
{
return this.RegisterExpressionMethod(method.Body, handler);
}

public RegistryInterceptionHandler Register<T>(Expression<Action<T>> method, IInterceptionHandler handler)
{
return this.RegisterExpressionMethod(method.Body, handler);
}

public void Invoke(InterceptionArgs arg)
{
IInterceptionHandler handler;

if (this.handlers.TryGetValue(arg.Method, out handler) == true)
{
handler.Invoke(arg);
}
}
}

Here you would have to explicitly register the methods you want to intercept (also works for properties), and, for each of these methods, its interception handler:

var registry = new RegistryInterceptionHandler();
registry.Register<IMyInterceptedType>(x => x.Method(), new MyInterceptionHandler());

All you need to do is implement Invoke, and off you go! To make it clear, any of these three implementations – RetriesInterceptionHandlerAttributesInterceptionHandler and RegistryInterceptionHandler – should be passed as the third argument to IInstanceInterceptor.Intercept:

var instance = new MyInterceptedType();
var interceptor = new InterfaceInterceptor();
var proxy = interceptor.Intercept(instance, typeof(IMyInterceptedType), new RetriesInterceptionHandler { Retries = 3, Delay = TimeSpan.FromSeconds(5) }) as IMyInterceptedType;

Conclusion

DevelopmentWithADot.Interception

I’ve shown some techniques that can be used to intercept .NET code in a number of scenarios. You basically need to pick your interceptor based on what you’ve got:

  • If you want to intercept a type (not an instance) that is not sealed or is abstract, you need to use VirtualMethodInterceptor, as it is the only type interceptor
  • If you want to intercept a particular interface, you can use one of InterfaceInterceptor, TransparentProxyInterceptor or DynamicInterceptor
  • If you want to intercept an instance of a class inheriting directly or indirectly from MarshalByRefObject, regardless of whether or not it implements some interface, you can use TransparentProxyInterceptor
  • If you want to intercept some type, whatever its base class or implemented interfaces are, and you are cool with using the dynamic keyword around it, use DynamicInterceptor
  • If you are OK with having a base class of ContextBoundObject, and you also don’t mind adding an obscure attribute to your class, you have ContextBoundObjectInterceptor 

Other scenarios, like intercepting static methods, can only be solved through IL weaving. Have a look at my previous post about it and see if it helps you.

Keep in mind that this code works as it should but it is not bulletproof. Let me know if you face any problems using it, or if you have any questions or remarks!

Interception in .NET – Part 3: Static Interception

Updated: see the last post in the series here.

Introduction

Part three of a series on interception in the .NET world. See the first part here and the second here.

This time I’m going to talk about static interception using PostSharp as an example. Static interceptors use information provided at code writing time – aspects – to do IL weaving. This basically means that after the .NET assembly is compiled, PostSharp rewrites the produced IL to apply the changes intended by the code developer, such as method interception. This is a good thing, as you can intercept types and methods regardless or not if they are virtual, static, implement some interface, etc.

This won’t be a full coverage of PostSharp, of course – which has far more than just interception – , but I include it in this series so that we see how it compares to other techniques.

Example Using PostSharp

Imagine you want to retry a certain method a number of times, this may be because what it does is sensible to network failures, or any other reason. In PostSharp, you would write a method interceptor aspect as this:

[PSerializable]
public class RetryOnExceptionAttribute : MethodInterceptionAspect
{
    public int MaxRetries { get; set; }

    public override void OnInvoke(MethodInterceptionArgs args)
    {
        int retriesCounter = 0;

        while ( true )
        {
            try
            {
                base.OnInvoke(args);
                return;
            }
            catch (Exception e)
            {
                retriesCounter++;
                if (retriesCounter > this.MaxRetries) throw;

                Console.WriteLine(
                    "Exception during attempt {0} of calling method {1}.{2}: {3}",
                    retriesCounter, args.Method.DeclaringType, args.Method.Name, e.Message);
            }
        }
    }
}

Note that you need to reference the Nuget package PostSharp.Patterns.Diagnostics, or any other that contains the PostSharp core assemblies.

And you could then apply it to some method:

public class CustomerService
{
    [RetryOnException(MaxRetries = 5)]
    public void Save(Customer customer)
    {
        // Database or web-service call.
    }
}

After Visual Studio (or, rather, MSBuild), builds your assembly, PostSharp pops in: it reads definitions present in the PostSharp.Custom.targets file and modifies that assembly to call the RetryOnExceptionAttribute’s OnInvoke method around the Customer.Save method, because the aspect was applied to it.

The MethodInterceptionAspect is not the only aspect class, there’s also:

After PostSharp modifies the assembly, it will no longer resemble your code: if you decompile it, you will see other stuff in there, like, a call to RetryOnExceptionAttribute.OnInvoke. Something like this:

[DebuggerTargetMethod(0x600000d), DebuggerBindingMethod(0x6000010)]
public void Save(Customer customer)
{
    try
    {
        Arguments<Customer> arguments = new Arguments<Customer> {
            Arg0 = customer
        };
        MethodInterceptionArgsImpl args = new MethodInterceptionArgsImpl(this, arguments) {
            DeclarationIdentifier = new DeclarationIdentifier(0x78acef3000030000L),
            Method = <>z__a_1._2,
            TypedBinding = <Save>c__Binding.singleton
        };
        <>z__a_1.a1.OnInvoke(args);
    }
    finally
    {
    }
}

Although hard to understand, rest assured that it does what you expect! Winking smile There are a bunch of additional types generated, but it’s really irrelevant to look at them.

Alternatives to PostSharp

There are some commercial alternatives and then there’s Mono.Cecil. Implemented as part of the Mono project – meaning, free and open source – it allows you to do low level IL weaving, but you should know what you are doing as there are none of the nice wrappers that PostSharp provides.

There are some interesting projects that make Mono.Cecil easier to use, and one of them is Fody. It is basically a wrapper around it, and is also open source. If you want to do things yourself, give it a try!

Conclusion

PostSharp is very powerful, as is IL weaving in general, but sometimes we need more than static interception. Here’s where dynamic interception kicks in. In the next post, I will start describing a framework for dynamic interception with a number of implementations. Stay tuned!

Entity Framework Pitfalls: Skip/Take Position Matters

In LINQ, you normally do paging through the Skip and Take operators. These are the LINQ counterparts to whatever the relational database uses for pagination – ROW_NUMBER(), LIMIT…OFFSET, TOP, ROWNUM, etc.

There are some gotchas to it:

  • When you do paging, Entity Framework demands that you add ordering to your query. This makes sense as without an explicit ORDER BY clause, search results may come in an unexpected order;
  • Skip and Take yield different results if added to different places in the LINQ expression.

Consider these two LINQ queries:

ctx
.MyEntities
.Where(x => x.Name == "")
.OrderBy(x => x.Id)
.Skip(10)
.Take(5)
.ToList();

And:

ctx
.MyEntities
.OrderBy(x => x.Id)
.Skip(10)
.Take(5)
.Where(x => x.Name == "")
.ToList();

The first one will produce this SQL:

SELECT TOP (5)
[Filter1].[Id] AS [Id],
[Filter1].[Name] AS [Name],
[Filter1].[Date] AS [Date]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].
[Date] AS [Date], row_number() OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number
]
FROM [dbo].[MyEntities] AS [Extent1]
WHERE N'' = [Extent1].[Name]
) AS [Filter1]
WHERE [Filter1].[row_number] > 10
ORDER BY [Filter1].[Id] ASC

Whereas the second will produce this one:

SELECT
[Limit1].[Id] AS [Id],
[Limit1].[Name] AS [Name],
[Limit1].[Date] AS [Date]
FROM ( SELECT TOP (5) [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[Date] AS [Date]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[Date] AS [Date], row_number() OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[MyEntities] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 10
ORDER BY [Extent1].[Id] ASC
) AS [Limit1]
WHERE N'' = [Limit1].[Name]
ORDER BY [Limit1].[Id] ASC

Basically, the TOP(5) expression is placed in the wrong place. So, in LINQ, it’s not just the presence of a Skip and Take operator, it’s where you place it that matters!

Visual Studio Tips 4

OK, so this is another round of tips on using Visual Studio! See first collection here, second here and third here.

  1. Create shortcuts: you can create shortcuts to frequently used code. Just click <Ctrl>KH on any line, and you will add a shortcut to it:

    image
    After that, you can jump to any of your bookmarks from the Task view:
    image
    To remove it, click <Ctrl>KH again in the same line. Note that this is not the same as the bookmarks featured introduced in the third set of tips!
  2. Code Maps: this requires Visual Studio Enterprise. Open the Architecture menu and select Generate Code Map for Solution.

    image
    You will get a nice diagram showing all dependencies between assemblies in your project:
    image
  3. Code Metrics: get a static analysis report of your project, only in Enterprise edition. In the Solution Explorer, right click on your project, Analyze, and select Calculate Code Metrics.

    You get an analysis including metrics Maintainability Index, Cyclomatic Complexity, Depth of Inheritance, Class Coupling and Lines of Code, which you can even export to Excel:
    image
  4. Format document on save & remove unused and sort using statements on save: Visual Studio can take care of formatting your documents and removing any unnecessary using declarations for you, when you save your documents; you just need to install the Productivity Power Tools extension and enable these options in ToolsProductivity Power ToolsPowerCommands:
    image
  5. Thread Deadlocks: Visual Studio can show you thread deadlocks while debugging. When debugging a multithreaded app, break it and open DebugWindowsTasks:
    image
    From here, you can flag your code so that it is more clearly visible.
  6. Executing code in Immediate Window: the Immediate Window can be used to run .NET code. While debugging your app, pause it, and select DebugWindowsImmediate:

    image
    You can enter any .NET expressions and variables or even complex expressions and see them evaluated at once.
  7. Pin and export Data Tips: while debugging, break and hover any variable or field in your code. Click the pin icon on the right of the tooltip window. This will create a Data Tip.
    image
    You can have multiple Data Tips, add comments to them:
    image
    Also save Data Tips to files so that they can be loaded in another Visual Studio session, and, of course, load a collection of Data Tips:
    image
  8. Place reusable code in Toolbox: you can add code that you use frequently to the Toolbox. Pin your Toolbox window, highlight your code and drag it to the Toolbox. Even if you are not working in a visual app, the code snippet can be dragged from the Toolbox into your code:
    image
  9. Change C# language version: Visual Studio can use any of the C# versions. For example you may or may not want to use the latest (and greatest, by the way!) features of C# 6. All you have to do is right click on a project, Properties, Build and Advanced. In the Advanced Build Settings window, Language Version, select the one you want to support:
    image
  10. Find tips: some tips related to the Find functionality. First, you have two results windows, 1 and 2, and you can have your search results appear in any of them:
    image
    With this, you can also append to current results or show only the file names that match the search pattern.

Coming Up Next

The following topics have been somewhat neglected… I promised to write follow ups to existing posts, but have been unable to so far. Hopefully I will resume them soon, in some cases I already started working on them:

As always, I’m keen to hear from you, so, do drop me a note if you have any questions or suggestions!

Entity Framework Pitfalls: Null Semantics

Imagine you have a simple class:

public class MyEntity
{
public int Id { get; set; }
public string Name { get; set; }
}

You may want to query it:

string name = ...;

var entities = ctx
.MyEntities
.Where(x => x.Name == name)
.ToList();

Entity Framework generates a query such as this:

SELECT [Extent1].[Id] AS Id, [Extent1].[Name] AS Name
FROM [dbo].[MyEntities] AS [Extent1]
WHERE ([Extent1].[Name] = @p__linq__0)
OR (([Extent1].[Name] IS NULL) AND (@p__linq__0 IS NULL))

Meaning: return all records from the MyEntities table if

  1. The Name column is identical to the name variable or
  2. Both the Name column and the name variable are NULL

Seems excessively complex, doesn’t it? Well, this is to account for the case where the name parameter is null. In  that case, a simple COLUMN = VALUE comparison won’t work, because in SQL, NULL = NULL returns FALSE! The syntax for comparing with NULL is COLUMN IS NULL. By generating this kind of query, Entity Framework is playing safe. Mind you, this only happens if you do not use the literal null, if you do, Entity Framework is smart enough to generate a simpler query:

var entities = ctx
.MyEntities
.Where(x => x.Name == null)
.ToList();

Results in:

SELECT [Extent1].[Id] AS Id, [Extent1].[Name] AS Name
FROM [dbo].[MyEntities] AS [Extent1]
WHERE ([Extent1].[Name] IS NULL)

However, there is a configuration setting, UseDatabaseNullSemantics (the opposite of the old UseCSharpNullComparisonBehavior of ObjectContext), that can be used to control this behavior. If set to true (the opposite of the default):

ctx.Configuration.UseDatabaseNullSemantics = true;

It generates all SQL queries as the unsafe version:

SELECT [Extent1].[Id] AS Id, [Extent1].[Name] AS Name
FROM [dbo].[MyEntities] AS [Extent1]
WHERE ([Extent1].[Name] = @p__linq__0)

The result is, even if you have a record whose Name column is NULL, it won’t be returned: remember that in SQL, by default, NULL <> NULL!

Therefore, if you are not 100% sure that the parameter that you will be using in the LINQ query will never be null, do not mess with UseDatabaseNullSemantics even if it generates somewhat poorer SQL.

Of course, if you are using SQL Server, you can set ANSI_NULLS to OFF, and the problem goes away; in that case, NULL = NULL.