Skip to content

Instantly share code, notes, and snippets.

@jdaigle
Created May 12, 2016 12:22
Show Gist options
  • Save jdaigle/aa10e138e2802b3c42c09e3c906c0fdc to your computer and use it in GitHub Desktop.
Save jdaigle/aa10e138e2802b3c42c09e3c906c0fdc to your computer and use it in GitHub Desktop.
public static class CommandHandlerRegistration
{
public static void Init()
{
// manual registration
Register<AddProductModel, int>((c, r) => ProductsCommandHandlers.AddProductModel(c, r.Resolve<DbContext>()));
Register<AddProductReview>((c, r) => ProductsCommandHandlers.AddProductReview(c, r.Resolve<CommandContext>()));
Register<SetProductModelName>((c, r) => ProductsCommandHandlers.SetProductModelName(c, r.Resolve<CommandContext>()));
}
private static void Register<TCommand>(Action<TCommand, IObjectResolver> handler)
where TCommand : IAPICommand<VoidResult>
{
Register<TCommand, VoidResult>((c, r) =>
{
handler(c, r);
return VoidResult.Value;
});
}
private static void Register<TCommand, TResult>(Func<TCommand, IObjectResolver, TResult> handler)
where TCommand : IAPICommand<TResult>
{
ParameterExpression lambdaTargetParameter = Expression.Parameter(typeof(object), "target");
ParameterExpression commandParameter = Expression.Parameter(typeof(object), "command");
ParameterExpression objectResolver = Expression.Parameter(typeof(IObjectResolver), "objectResolver");
UnaryExpression lambdaTargetParameterCast = Expression.Convert(lambdaTargetParameter, handler.Target.GetType());
UnaryExpression commandParameterCast = Expression.Convert(commandParameter, typeof(TCommand));
MethodCallExpression methodCall = methodCall = Expression.Call(lambdaTargetParameterCast, handler.Method, commandParameterCast, objectResolver);
UnaryExpression castMethodCall = Expression.Convert(methodCall, typeof(object));
var lambda = Expression.Lambda<Func<object, object, IObjectResolver, object>>(castMethodCall, lambdaTargetParameter, commandParameter, objectResolver);
var compiled = lambda.Compile();
commandHandlers[typeof(TCommand)] = new Func<object, IObjectResolver, object>((c, r) => compiled(handler.Target, c, r));
}
private static readonly Dictionary<Type, Func<object, IObjectResolver, object>> commandHandlers = new Dictionary<Type, Func<object, IObjectResolver, object>>();
public static IReadOnlyDictionary<Type, Func<object, IObjectResolver, object>> CommandHandlers
{
get { return commandHandlers; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment