public override Type Generate(Type type) { var aggregateTypeDetails = TypeAnalyzer.GetTypeDetail(aggregateType); if (!aggregateTypeDetails.BaseTypes.Contains(aggregateRootType)) { throw new Exception($"{nameof(TransactStoreEntityAttribute)} {nameof(aggregateType)} argument {type.Name} does not inherit {aggregateRootType.Name}"); } var typeDetail = TypeAnalyzer.GetTypeDetail(type); if (!typeDetail.BaseTypes.Contains(dataContextType)) { throw new Exception($"{nameof(TransactStoreEntityAttribute)} is not placed on a {dataContextType.Name}"); } var baseType = TypeAnalyzer.GetGenericType(eventProviderType, type, aggregateType); var typeSignature = $"{aggregateType.Name}_{type.Name}_Provider"; var moduleBuilder = GeneratedAssembly.GetModuleBuilder(); var typeBuilder = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, baseType); _ = typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); var objectType = typeBuilder.CreateTypeInfo(); return(objectType); }
private static Type GenerateProviderToCallInternalClass(Type interfaceType) { if (!interfaceType.IsInterface) { throw new ArgumentException($"Type {interfaceType.GetNiceName()} is not an interface"); } var inheritsBaseProvider = false; var methods = new List <MethodInfo>(); var notSupportedMethods = new List <MethodInfo>(); methods.AddRange(interfaceType.GetMethods()); foreach (var @interface in interfaceType.GetInterfaces()) { if (!inheritsBaseProvider && @interface == baseProviderType) { inheritsBaseProvider = true; } if (@interface.GetInterfaces().Contains(baseProviderType)) { methods.AddRange(@interface.GetMethods()); } else { notSupportedMethods.AddRange(@interface.GetMethods()); } } if (!inheritsBaseProvider) { throw new ArgumentException($"Type {interfaceType.GetNiceName()} does not inherit {baseProviderType.GetNiceName()}"); } string typeSignature = interfaceType.Name + "_Caller"; var moduleBuilder = GeneratedAssembly.GetModuleBuilder(); var typeBuilder = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null); typeBuilder.AddInterfaceImplementation(interfaceType); _ = typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); foreach (var method in methods) { var methodName = method.Name; var returnType = method.ReturnType; Type[] parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray(); bool voidMethod = false; if (returnType.Name == "Void") { returnType = typeof(object); voidMethod = true; } var callMethod = callInternalMethodNonGeneric.MakeGenericMethod(interfaceType, returnType); var methodBuilder = typeBuilder.DefineMethod( methodName, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis, voidMethod ? null : returnType, parameterTypes); methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed); var il = methodBuilder.GetILGenerator(); il.DeclareLocal(typeof(object[])); il.DeclareLocal(returnType); il.DeclareLocal(typeof(object[])); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldc_I4, parameterTypes.Length); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc_2); for (int j = 0; j < parameterTypes.Length; j++) { il.Emit(OpCodes.Ldloc_2); il.Emit(OpCodes.Ldc_I4, j); il.Emit(OpCodes.Ldarg, j + 1); il.Emit(OpCodes.Box, parameterTypes[j]); il.Emit(OpCodes.Stelem_Ref); } il.Emit(OpCodes.Ldloc_2); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldstr, methodName); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Call, callMethod); if (voidMethod) { il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ret); } else { il.Emit(OpCodes.Stloc_1); Label ender = il.DefineLabel(); il.Emit(OpCodes.Br_S, ender); il.MarkLabel(ender); il.Emit(OpCodes.Ldloc_1); il.Emit(OpCodes.Ret); } typeBuilder.DefineMethodOverride(methodBuilder, method); } foreach (var method in notSupportedMethods) { string methodName = method.Name; var returnType = method.ReturnType; Type[] parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray(); bool voidMethod = false; if (returnType.Name == "Void") { returnType = typeof(object); voidMethod = true; } var methodBuilder = typeBuilder.DefineMethod( methodName, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis, voidMethod ? null : returnType, parameterTypes); methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed); var il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldstr, $"Interface method does not inherit {baseProviderType.Name}"); il.Emit(OpCodes.Newobj, notSupportedExceptionConstructor); il.Emit(OpCodes.Throw); typeBuilder.DefineMethodOverride(methodBuilder, method); } Type objectType = typeBuilder.CreateTypeInfo(); return(objectType); }
private static Type Generate(MemberInfo memberInfo, CoreType?coreType, bool isByteArray) { var interfaceType = TypeAnalyzer.GetGenericType(iCoreTypeSetterType, memberInfo.ReflectedType); string typeSignature = $"{interfaceType.FullName}_{memberInfo.Name}_CoreTypeSetterGenerator"; var moduleBuilder = GeneratedAssembly.GetModuleBuilder(); var typeBuilder = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null); typeBuilder.AddInterfaceImplementation(interfaceType); _ = typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); var methods = interfaceType.GetMethods().ToList(); var properties = interfaceType.GetProperties().ToList(); foreach (var @interface in interfaceType.GetInterfaces()) { methods.AddRange(@interface.GetMethods()); properties.AddRange(@interface.GetProperties()); } foreach (var method in methods) { if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) { continue; } Type[] parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray(); var methodBuilder = typeBuilder.DefineMethod( method.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis, null, parameterTypes ); methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed); var il = methodBuilder.GetILGenerator(); CoreType?methodCoreType; bool methodIsByteArray; if (TypeLookup.CoreTypeLookup(parameterTypes[1], out CoreType coreTypeLookup)) { methodCoreType = coreTypeLookup; methodIsByteArray = false; } else { methodCoreType = null; methodIsByteArray = parameterTypes[1] == byteArrayType; } if (coreType == methodCoreType && isByteArray == methodIsByteArray) { if (memberInfo.MemberType == MemberTypes.Property) { var propertyInfo = (PropertyInfo)memberInfo; var setMethod = propertyInfo.GetSetMethod(true); if (!setMethod.IsStatic) { il.Emit(OpCodes.Ldarg_1); } il.Emit(OpCodes.Ldarg_2); if (setMethod.IsFinal || !setMethod.IsVirtual) { il.Emit(OpCodes.Call, setMethod); } else { il.Emit(OpCodes.Callvirt, setMethod); } il.Emit(OpCodes.Ret); } else if (memberInfo.MemberType == MemberTypes.Field) { var fieldInfo = (FieldInfo)memberInfo; if (!fieldInfo.IsStatic) { il.Emit(OpCodes.Ldarg_1); if (fieldInfo.ReflectedType.IsValueType) { il.Emit(OpCodes.Unbox, fieldInfo.ReflectedType); } } il.Emit(OpCodes.Ldarg_2); if (!fieldInfo.IsStatic) { il.Emit(OpCodes.Stfld, fieldInfo); } else { il.Emit(OpCodes.Stsfld, fieldInfo); } il.Emit(OpCodes.Ret); } else { throw new NotImplementedException(); } } else { il.Emit(OpCodes.Newobj, notSupportedExceptionConstructor); il.Emit(OpCodes.Throw); } typeBuilder.DefineMethodOverride(methodBuilder, method); } foreach (var property in properties) { var propertyBuilder = typeBuilder.DefineProperty( property.Name, PropertyAttributes.HasDefault, property.PropertyType, null ); var getMethodName = "get_" + property.Name; var getMethodBuilder = typeBuilder.DefineMethod( getMethodName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, property.PropertyType, Type.EmptyTypes ); var getMethodBuilderIL = getMethodBuilder.GetILGenerator(); if (property.Name == nameof(ICoreTypeSetter <object> .CoreType)) { if (coreType.HasValue) { getMethodBuilderIL.Emit(OpCodes.Ldc_I4, (int)coreType.Value); getMethodBuilderIL.Emit(OpCodes.Newobj, coreTypeNullableConstructor); } else { getMethodBuilderIL.Emit(OpCodes.Ldnull); } } else if (property.Name == nameof(ICoreTypeSetter <object> .IsByteArray)) { if (isByteArray) { getMethodBuilderIL.Emit(OpCodes.Ldc_I4_1); } else { getMethodBuilderIL.Emit(OpCodes.Ldc_I4_0); } } else { throw new NotImplementedException(); } getMethodBuilderIL.Emit(OpCodes.Ret); var getMethod = methods.FirstOrDefault(x => x.Name == getMethodName); typeBuilder.DefineMethodOverride(getMethodBuilder, getMethod); propertyBuilder.SetGetMethod(getMethodBuilder); } Type objectType = typeBuilder.CreateTypeInfo(); return(objectType); }
private static Type GenerateEventHandlerToDispatchInternalClass(Type interfaceType) { if (!interfaceType.IsInterface) { throw new ArgumentException($"Type {interfaceType.GetNiceName()} is not an interface"); } var inheritsBaseProvider = false; var methods = new List <MethodInfo>(); var notSupportedMethods = new List <MethodInfo>(); foreach (var @interface in interfaceType.GetInterfaces()) { if (!inheritsBaseProvider && @interface == baseProviderType) { inheritsBaseProvider = true; } if (@interface.Name == eventHandlerType.Name) { methods.AddRange(@interface.GetMethods()); } else { notSupportedMethods.AddRange(@interface.GetMethods()); } } if (!inheritsBaseProvider) { throw new ArgumentException($"Type {interfaceType.GetNiceName()} does not inherit {baseProviderType.GetNiceName()}"); } string typeSignature = interfaceType.Name + "_EventDispatcher"; var moduleBuilder = GeneratedAssembly.GetModuleBuilder(); var typeBuilder = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null); typeBuilder.AddInterfaceImplementation(interfaceType); _ = typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); foreach (var method in methods) { string methodName = method.Name; Type[] parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray(); var methodBuilder = typeBuilder.DefineMethod( methodName, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis, taskType, parameterTypes); methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed); var il = methodBuilder.GetILGenerator(); il.DeclareLocal(typeof(Type)); il.Emit(OpCodes.Nop); // Type messageType = @event.GetType(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Callvirt, getTypeMethod); il.Emit(OpCodes.Stloc_0); // Bus._DispatchEventInternalAsync(@event, eventType) il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Call, dispatchEventInternalAsyncMethod); il.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, method); } foreach (var method in notSupportedMethods) { var methodName = method.Name; Type[] parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray(); var methodBuilder = typeBuilder.DefineMethod( methodName, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis, taskType, parameterTypes); methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed); ILGenerator il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldstr, $"Interface method does not inherit {eventHandlerType.Name}"); il.Emit(OpCodes.Newobj, notSupportedExceptionConstructor); il.Emit(OpCodes.Throw); typeBuilder.DefineMethodOverride(methodBuilder, method); } Type objectType = typeBuilder.CreateTypeInfo(); return(objectType); }
public override Type Generate(Type type) { var entityTypeDetail = TypeAnalyzer.GetTypeDetail(entityType); if (!entityTypeDetail.Attributes.Select(x => x.GetType()).Contains(entityAttributeType)) { throw new Exception($"{nameof(TransactStoreEntityAttribute)} {nameof(entityType)} argument {type.Name} does not inherit {entityAttributeType.Name}"); } var typeDetail = TypeAnalyzer.GetTypeDetail(type); if (!typeDetail.BaseTypes.Contains(dataContextType)) { throw new Exception($"{nameof(TransactStoreEntityAttribute)} is not placed on a {dataContextType.Name}"); } var baseType = TypeAnalyzer.GetGenericType(providerType, type, entityType); var typeSignature = $"{entityType.Name}_{type.Name}_Provider"; var moduleBuilder = GeneratedAssembly.GetModuleBuilder(); var typeBuilder = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, baseType); _ = typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); var properties = new HashSet <Tuple <PropertyInfo, bool> >(); var transactProviderTypeDetails = TypeAnalyzer.GetTypeDetail(baseType); var methods = transactProviderTypeDetails.MethodDetails.Select(x => x.MethodInfo).ToArray(); if (eventLinking.HasValue) { var eventLinkingProperty = transactProviderTypeDetails.GetMember("EventLinking"); properties.Add(new Tuple <PropertyInfo, bool>((PropertyInfo)eventLinkingProperty.MemberInfo, eventLinking.Value)); } if (queryLinking.HasValue) { var queryLinkingProperty = transactProviderTypeDetails.GetMember("QueryLinking"); properties.Add(new Tuple <PropertyInfo, bool>((PropertyInfo)queryLinkingProperty.MemberInfo, queryLinking.Value)); } if (persistLinking.HasValue) { var eventLinkingProperty = transactProviderTypeDetails.GetMember("PersistLinking"); properties.Add(new Tuple <PropertyInfo, bool>((PropertyInfo)eventLinkingProperty.MemberInfo, persistLinking.Value)); } foreach (var prop in properties) { var property = prop.Item1; var value = prop.Item2; var propertyBuilder = typeBuilder.DefineProperty( property.Name, PropertyAttributes.HasDefault, property.PropertyType, null ); var getMethodName = "get_" + property.Name; var getMethod = methods.FirstOrDefault(x => x.Name == getMethodName); var getMethodBuilder = typeBuilder.DefineMethod( getMethodName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.Final, property.PropertyType, Type.EmptyTypes ); var getMethodBuilderIL = getMethodBuilder.GetILGenerator(); if (value) { getMethodBuilderIL.Emit(OpCodes.Ldc_I4_1); } else { getMethodBuilderIL.Emit(OpCodes.Ldc_I4_0); } getMethodBuilderIL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(getMethodBuilder, getMethod); propertyBuilder.SetGetMethod(getMethodBuilder); } var objectType = typeBuilder.CreateTypeInfo(); return(objectType); }