Skip to content

Instantly share code, notes, and snippets.

@ReubenBond
Last active April 30, 2017 05:51
Show Gist options
  • Save ReubenBond/480f1edbb3a12580515a to your computer and use it in GitHub Desktop.
Save ReubenBond/480f1edbb3a12580515a to your computer and use it in GitHub Desktop.
Taking part in Service Fabric transactions
using System;
using System.Collections.Concurrent;
using System.Fabric.Replication;
using System.Reflection;
using System.Reflection.Emit;
using Microsoft.ServiceFabric.Data;
internal static class TransactionExtensions
{
/// <summary>
/// The get transaction for type.
/// </summary>
private static readonly ConcurrentDictionary<Type, Func<ITransaction, Transaction>> GetTransactionForType =
new ConcurrentDictionary<Type, Func<ITransaction, Transaction>>();
public static Transaction GetTransaction(this ITransaction tx)
{
// Note: this is ugly, but this is currently the cleanest way to co-operate with System.Fabric.Data's transactions.
var getTransaction = GetTransactionForType.GetOrAdd(
tx.GetType(),
type =>
{
// Find the transaction property and its getter.
var property = type.GetProperty(
"Transaction",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.FlattenHierarchy);
var getMethod = property.GetGetMethod();
// Create a method to retrieve the transaction property given an instance of this type.
var method = new DynamicMethod(
type.Name + "_GetTransaction",
typeof(Transaction),
new[] { typeof(ITransaction) },
typeof(TransactionExtensions).Module,
skipVisibility: true);
// Emit IL to return the value of the Transaction property.
var emitter = method.GetILGenerator();
emitter.Emit(OpCodes.Ldarg_0);
emitter.Emit(OpCodes.Castclass, type);
emitter.EmitCall(OpCodes.Call, getMethod, null);
emitter.Emit(OpCodes.Ret);
var result = method.CreateDelegate(typeof(Func<ITransaction, Transaction>));
return (Func<ITransaction, Transaction>)result;
});
return getTransaction(tx);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment