为什么小巧玲珑的发光IL代码在CreateTableConstructor?
问题描述:
我看优秀的小巧玲珑的微型ORM,并在Dapper.Rainbow项目,有一些代码,创建一个表构造函数,使用IL。我希望这是什么代码做什么有人可以给我解释一下 - 显然,这是动态的发光代码来创建一个构造函数(或者是它的代码来调用构造函数,或两者),但什么是真实而实际发射创建代码,为什么这是需要的吗?为什么小巧玲珑的发光IL代码在CreateTableConstructor?
下面的代码
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>));
}
答
基本上,它需要看起来有点像当前类型(从Database<T>
派生)的所有属性:
public Table<SomeEntity> SomeTable { get; private set; }
,并创建一个委托执行类似的代码为每个这样的属性如下:
var table = new Table<SomeEntity>(db, "SomeTable");
db.SomeTable = table;
虽然我并不有助于幻灯克拉这似乎是建立一个构造中,它可以从数据库模型直接设定模型的值。它只是生成锅炉板代码。 – 2013-04-10 13:41:50
感谢您的评论和编辑。那么,什么是C#相当于该IL代码构造函数 - 而它这样做是为了救我不必这些构建函数添加到我的所有模型类? – 2013-04-10 13:52:15