/// <summary> /// Creates an object of the specified base type, registering the type if necessary /// </summary> /// <param name="BaseType">The base type</param> /// <returns>Returns an object of the specified base type</returns> public virtual object Create(Type BaseType) { if (!Classes.ContainsKey(BaseType)) { Setup(BaseType); } object ReturnObject = Classes[BaseType].Assembly.CreateInstance(Classes[BaseType].FullName); Aspects.ForEach(x => x.Setup(ReturnObject)); return(ReturnObject); }
private void SetupMethod(Type BaseType, IMethodBuilder Method, IPropertyBuilder AspectusStarting, IPropertyBuilder AspectusEnding, IPropertyBuilder AspectusException, MethodInfo BaseMethod) { if (BaseMethod == null) { BaseMethod = BaseType.GetMethod(Method.Name); } Method.SetCurrentMethod(); System.Reflection.Emit.Label EndLabel = Method.Generator.DefineLabel(); VariableBase ReturnValue = Method.ReturnType != typeof(void) ? Method.CreateLocal("FinalReturnValue", Method.ReturnType) : null; Utilities.Reflection.Emit.Commands.Try Try = Method.Try(); { SetupStart(Method, EndLabel, ReturnValue, AspectusStarting); Aspects.ForEach(x => x.SetupStartMethod(Method, BaseType)); List <ParameterBuilder> Parameters = new List <ParameterBuilder>(); Method.Parameters.For(1, Method.Parameters.Count - 1, x => Parameters.Add(x)); if (Method.ReturnType != typeof(void) && BaseMethod != null) { ReturnValue.Assign(Method.This.Call(BaseMethod, Parameters.ToArray())); } else if (BaseMethod != null) { Method.This.Call(BaseMethod, Parameters.ToArray()); } SetupEnd(Method, ReturnValue, AspectusEnding); Aspects.ForEach(x => x.SetupEndMethod(Method, BaseType, ReturnValue)); Method.Generator.MarkLabel(EndLabel); } Utilities.Reflection.Emit.Commands.Catch Catch = Try.StartCatchBlock(typeof(System.Exception)); { SetupException(Method, Catch, AspectusException); Aspects.ForEach(x => x.SetupExceptionMethod(Method, BaseType)); Catch.Rethrow(); } Try.EndTryBlock(); if (Method.ReturnType != typeof(void)) { Method.Return(ReturnValue); } else { Method.Return(); } }
/// <summary> /// Generates the specified type. /// </summary> /// <param name="namespace">The namespace.</param> /// <param name="className">Name of the class.</param> /// <param name="usings">The usings.</param> /// <param name="interfaces">The interfaces.</param> /// <param name="assembliesUsing">The assemblies using.</param> /// <returns>The string representation of the generated class</returns> public string Generate(string @namespace, string className, List <string> usings, List <Type> interfaces, List <Assembly> assembliesUsing) { var Builder = new StringBuilder(); Builder.AppendLineFormat(@"namespace {1} {{ {0} public class {2} : {3}{4} {5} {{ ", usings.ToString(x => "using " + x + ";", "\r\n"), @namespace, className, DeclaringType.FullName.Replace("+", "."), interfaces.Count > 0 ? "," : "", interfaces.ToString(x => x.Name)); if (DeclaringType.HasDefaultConstructor() || DeclaringType.IsInterface) { Builder.AppendLine(new ConstructorGenerator(DeclaringType.GetConstructors(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(x => x.GetParameters().Length == 0), DeclaringType) .Generate(assembliesUsing, Aspects)); } Aspects.ForEach(x => Builder.AppendLine(x.SetupInterfaces(DeclaringType))); Type TempType = DeclaringType; var MethodsAlreadyDone = new List <string>(); while (TempType != null) { foreach (PropertyInfo Property in TempType.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)) { MethodInfo GetMethodInfo = Property.GetGetMethod(); MethodInfo SetMethodInfo = Property.GetSetMethod(); if (!MethodsAlreadyDone.Contains("get_" + Property.Name) && !MethodsAlreadyDone.Contains("set_" + Property.Name) && GetMethodInfo != null && GetMethodInfo.IsVirtual && SetMethodInfo != null && SetMethodInfo.IsPublic && !GetMethodInfo.IsFinal && Property.GetIndexParameters().Length == 0) { Builder.AppendLine(new PropertyGenerator(Property).Generate(assembliesUsing, Aspects)); MethodsAlreadyDone.Add(GetMethodInfo.Name); MethodsAlreadyDone.Add(SetMethodInfo.Name); } else if (!MethodsAlreadyDone.Contains("get_" + Property.Name) && GetMethodInfo != null && GetMethodInfo.IsVirtual && SetMethodInfo == null && !GetMethodInfo.IsFinal && Property.GetIndexParameters().Length == 0) { Builder.AppendLine(new PropertyGenerator(Property).Generate(assembliesUsing, Aspects)); MethodsAlreadyDone.Add(GetMethodInfo.Name); } else { if (GetMethodInfo != null) { MethodsAlreadyDone.Add(GetMethodInfo.Name); } if (SetMethodInfo != null) { MethodsAlreadyDone.Add(SetMethodInfo.Name); } } } foreach (MethodInfo Method in TempType.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance) .Where(x => !MethodsAlreadyDone.Contains(x.Name) && x.IsVirtual && !x.IsFinal && !x.IsPrivate && !x.Name.StartsWith("add_", StringComparison.InvariantCultureIgnoreCase) && !x.Name.StartsWith("remove_", StringComparison.InvariantCultureIgnoreCase) && !x.IsGenericMethod)) { Builder.AppendLine(new MethodGenerator(Method).Generate(assembliesUsing, Aspects)); MethodsAlreadyDone.Add(Method.Name); } TempType = TempType.BaseType; if (TempType == typeof(object)) { break; } } Builder.AppendLine(@" } }"); return(Builder.ToString()); }
/// <summary> /// Sets up a type so it can be used in the system later /// </summary> /// <param name="Type">Type to set up</param> public virtual void Setup(Type Type) { if (Classes.ContainsKey(Type)) { return; } if (new FileInfo(AssemblyDirectory + AssemblyName + ".dll").Exists && !RegenerateAssembly) { throw new ArgumentException("Type specified not found and can't be generated due to being in 'GoDaddy' mode. Delete already generated DLL to add new types or set RegenerateAssembly to true."); } List <Type> Interfaces = new List <Type>(); Aspects.ForEach(x => Interfaces.AddRange(x.InterfacesUsing == null ? new List <Type>() : x.InterfacesUsing)); Interfaces.Add(typeof(IEvents)); Utilities.Reflection.Emit.TypeBuilder Builder = AssemblyBuilder.CreateType(AssemblyName + "." + Type.Name + "Derived", System.Reflection.TypeAttributes.Class | System.Reflection.TypeAttributes.Public, Type, Interfaces); { IPropertyBuilder AspectusStarting = Builder.CreateDefaultProperty("Aspectus_Starting", typeof(EventHandler <Starting>)); IPropertyBuilder AspectusEnding = Builder.CreateDefaultProperty("Aspectus_Ending", typeof(EventHandler <Ending>)); IPropertyBuilder AspectusException = Builder.CreateDefaultProperty("Aspectus_Exception", typeof(EventHandler <Utilities.Reflection.AOP.EventArgs.Exception>)); Aspects.ForEach(x => x.SetupInterfaces(Builder)); Type TempType = Type; List <string> MethodsAlreadyDone = new List <string>(); while (TempType != null) { foreach (PropertyInfo Property in TempType.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)) { MethodInfo GetMethodInfo = Property.GetGetMethod(); if (!MethodsAlreadyDone.Contains("get_" + Property.Name) && !MethodsAlreadyDone.Contains("set_" + Property.Name) && GetMethodInfo != null && GetMethodInfo.IsVirtual && !GetMethodInfo.IsFinal) { IPropertyBuilder OverrideProperty = Builder.CreateProperty(Property.Name, Property.PropertyType, System.Reflection.PropertyAttributes.SpecialName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual); { IMethodBuilder Get = OverrideProperty.GetMethod; { SetupMethod(Type, Get, AspectusStarting, AspectusEnding, AspectusException, null); MethodsAlreadyDone.Add(Get.Name); } IMethodBuilder Set = OverrideProperty.SetMethod; { SetupMethod(Type, Set, AspectusStarting, AspectusEnding, AspectusException, null); MethodsAlreadyDone.Add(Set.Name); } } } } foreach (MethodInfo Method in TempType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)) { if (!MethodsAlreadyDone.Contains(Method.Name) && Method.IsVirtual && !Method.IsFinal) { MethodAttributes MethodAttribute = MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public; if (Method.IsStatic) { MethodAttribute |= MethodAttributes.Static; } List <Type> ParameterTypes = new List <Type>(); Method.GetParameters().ForEach(x => ParameterTypes.Add(x.ParameterType)); IMethodBuilder OverrideMethod = Builder.CreateMethod(Method.Name, MethodAttribute, Method.ReturnType, ParameterTypes); SetupMethod(Type, OverrideMethod, AspectusStarting, AspectusEnding, AspectusException, Method); MethodsAlreadyDone.Add(Method.Name); } } TempType = TempType.BaseType; if (TempType == typeof(object)) { break; } } Classes.Add(Type, Builder.Create()); } }