private Delegate BuildDelegate(OpaqueType methodType, Type targetType) { Exception wrap = null; try { foreach (var build in _builders[methodType]) { Delegate result = build(targetType); if (result != null) { return(result); } } } catch (Exception ex) { wrap = new InvalidOperationException( string.Format("impossible to create a {0} method type for `{1}'", methodType, targetType.FullName), ex); } if (wrap == null) { wrap = new NotImplementedException(string.Format("unknown type `{0}' in {1} method type", targetType.FullName, methodType)); } if (methodType == OpaqueType.One) { return(ErrorStub.ReadOneDelegate(targetType, wrap)); } else { return(ErrorStub.ReadManyDelegate(targetType, wrap)); } }
protected void AppendBuildRequest(Type targetType, OpaqueType methodType) { lock (_dependencySync) _dependency.Enqueue(new BuildRequest { TargetType = targetType, Method = methodType }); }
private void LockedAppendMethod(Type targetType, OpaqueType methodType, Delegate method) { FieldInfo fi = GetCacheType(methodType).MakeGenericType(targetType).GetField("Instance"); if (fi.GetValue(null) != null) { throw new InvalidOperationException("type already mapped"); } fi.SetValue(null, method); }
private Type GetCacheType(OpaqueType methodType) { switch (methodType) { case OpaqueType.One: return(GetOneCacheType()); case OpaqueType.Fix: return(GetFixCacheType()); case OpaqueType.Var: return(GetVarCacheType()); default: throw new NotImplementedException("unknown opaque type"); } }
public StaticCacheDescription(ModuleBuilder modBuilder, BuildBinderDescription delegCacheDesc, string name, bool read, OpaqueType mType) { TypeBuilder typeBuilder = modBuilder.DefineType(name, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Abstract | TypeAttributes.Sealed); GenericTypeParameterBuilder genTypeParam = typeBuilder.DefineGenericParameters("T")[0]; Type instanceType; if(read) { if (mType == OpaqueType.One) instanceType = typeof(ReadOneDelegate<>); else instanceType = typeof(ReadManyDelegate<>); } else { if (mType == OpaqueType.One) instanceType = typeof(WriteOneDelegate<>); else instanceType = typeof(WriteManyDelegate<>); } typeBuilder.DefineField("Instance", instanceType.MakeGenericType(genTypeParam), FieldAttributes.Public | FieldAttributes.Static); ConstructorBuilder ctor = typeBuilder.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, new Type[0]); ILGenerator il = ctor.GetILGenerator(); il.Emit(OpCodes.Ldsfld, delegCacheDesc.BuildRequest); il.Emit(OpCodes.Ldtoken, genTypeParam); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); il.Emit(OpCodes.Ldc_I4_S, (int)mType); il.Emit(OpCodes.Callvirt, typeof(Action<Type, OpaqueType>).GetMethod("Invoke")); il.Emit(OpCodes.Ret); Result = typeBuilder.CreateType(); }
public StaticCacheDescription(ModuleBuilder modBuilder, BuildBinderDescription delegCacheDesc, string name, bool read, OpaqueType mType) { TypeBuilder typeBuilder = modBuilder.DefineType(name, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Abstract | TypeAttributes.Sealed); GenericTypeParameterBuilder genTypeParam = typeBuilder.DefineGenericParameters("T")[0]; Type instanceType; if (read) { if (mType == OpaqueType.One) { instanceType = typeof(ReadOneDelegate <>); } else { instanceType = typeof(ReadManyDelegate <>); } } else { if (mType == OpaqueType.One) { instanceType = typeof(WriteOneDelegate <>); } else { instanceType = typeof(WriteManyDelegate <>); } } typeBuilder.DefineField("Instance", instanceType.MakeGenericType(genTypeParam), FieldAttributes.Public | FieldAttributes.Static); ConstructorBuilder ctor = typeBuilder.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, new Type[0]); ILGenerator il = ctor.GetILGenerator(); il.Emit(OpCodes.Ldsfld, delegCacheDesc.BuildRequest); il.Emit(OpCodes.Ldtoken, genTypeParam); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); il.Emit(OpCodes.Ldc_I4_S, (int)mType); il.Emit(OpCodes.Callvirt, typeof(Action <Type, OpaqueType>).GetMethod("Invoke")); il.Emit(OpCodes.Ret); Result = typeBuilder.CreateType(); }
internal void AppendMethod(Type targetType, OpaqueType methodType, Delegate method) { lock (_sync) LockedAppendMethod(targetType, methodType, method); }