我正在寻找优秀的Dapper微观,在Dapper.Rainbow项目中,有一些代码使用IL创建了一个表ctor。我希望有人可以向我解释这段代码在做什么 - 显然它是动态发出代码来创建一个构造函数(或者它是调用构造函数的代码,或两者兼而有之),但是实际创建的代码是什么,以及为什么这需要吗?
这是代码
protected Action<TDatabase> CreateTableConstructor(Type tableType)
{
var dm = new DynamicMethod("ConstructInstances", null, new Type[] { typeof(TDatabase) }, true);
var il = dm.GetILGenerator();
var setters = GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == tableType)
.Select(p => Tuple.Create(
p.GetSetMethod(true),
p.PropertyType.GetConstructor(new Type[] { typeof(TDatabase), typeof(string) }),
p.Name,
p.DeclaringType
));
foreach (var setter in setters)
{
il.Emit(OpCodes.Ldarg_0);
// [db]
il.Emit(OpCodes.Ldstr, setter.Item3);
// [db, likelyname]
il.Emit(OpCodes.Newobj, setter.Item2);
// [table]
var table = il.DeclareLocal(setter.Item2.DeclaringType);
il.Emit(OpCodes.Stloc, table);
// []
il.Emit(OpCodes.Ldarg_0);
// [db]
il.Emit(OpCodes.Castclass, setter.Item4);
// [db cast to container]
il.Emit(OpCodes.Ldloc, table);
// [db cast to container, table]
il.Emit(OpCodes.Callvirt, setter.Item1);
// []
}
il.Emit(OpCodes.Ret);
return (Action<TDatabase>)dm.CreateDelegate(typeof(Action<TDatabase>));
}
答案 0 :(得分:3)
基本上,它采用当前类型的所有属性(源自Database<T>
),如下所示:
public Table<SomeEntity> SomeTable { get; private set; }
创建一个委托,为每个这样的属性执行如下代码:
var table = new Table<SomeEntity>(db, "SomeTable");
db.SomeTable = table;