void CreateInitializer()
{
EnsureClientTypeVersion();
var tableVersionInfo = ClientTableVersionInfo;
var method = ILBuilder.Instance.NewMethod<Action<IInternalObjectDBTransaction, DBObjectMetadata, object>>(
$"Initializer_{Name}");
var ilGenerator = method.Generator;
if (tableVersionInfo.NeedsInit())
{
ilGenerator.DeclareLocal(ClientType);
ilGenerator
.Ldarg(2)
.Castclass(ClientType)
.Stloc(0);
var anyNeedsCtx = tableVersionInfo.NeedsCtx();
if (anyNeedsCtx)
{
ilGenerator.DeclareLocal(typeof(IReaderCtx));
ilGenerator
.Ldarg(0)
.Newobj(() => new DBReaderCtx(null))
.Stloc(1);
}
var props = _clientType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
for (int fi = 0; fi < tableVersionInfo.FieldCount; fi++)
{
var srcFieldInfo = tableVersionInfo[fi];
var iFieldHandlerWithInit = srcFieldInfo.Handler as IFieldHandlerWithInit;
if (iFieldHandlerWithInit == null) continue;
Action<IILGen> readerOrCtx;
if (srcFieldInfo.Handler.NeedsCtx())
readerOrCtx = il => il.Ldloc(1);
else
readerOrCtx = il => il.Ldnull();
var specializedSrcHandler = srcFieldInfo.Handler;
var willLoad = specializedSrcHandler.HandledType();
var setterMethod = props.First(p => GetPersistantName(p) == srcFieldInfo.Name).GetSetMethod(true);
var converterGenerator = _tableInfoResolver.TypeConvertorGenerator.GenerateConversion(willLoad, setterMethod.GetParameters()[0].ParameterType);
if (converterGenerator == null) continue;
if (!iFieldHandlerWithInit.NeedInit()) continue;
ilGenerator.Ldloc(0);
iFieldHandlerWithInit.Init(ilGenerator, readerOrCtx);
converterGenerator(ilGenerator);
ilGenerator.Call(setterMethod);
}
}
ilGenerator.Ret();
var initializer = method.Create();
Interlocked.CompareExchange(ref _initializer, initializer, null);
}