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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }