/// <summary>
 /// Constructor
 /// </summary>
 /// <param name="TypeBuilder">Type builder</param>
 /// <param name="Name">Name of the method</param>
 /// <param name="Attributes">Attributes for the method (public, private, etc.)</param>
 /// <param name="Parameters">Parameter types for the method</param>
 /// <param name="ReturnType">Return type for the method</param>
 public MethodBuilder(TypeBuilder TypeBuilder, string Name,
     MethodAttributes Attributes, List<Type> Parameters, Type ReturnType)
     : base()
 {
     if (TypeBuilder == null)
         throw new ArgumentNullException("TypeBuilder");
     if (string.IsNullOrEmpty(Name))
         throw new ArgumentNullException("Name");
     this.Name = Name;
     this.Type = TypeBuilder;
     this.Attributes = Attributes;
     this.ReturnType = (ReturnType == null) ? typeof(void) : ReturnType;
     this.Parameters = new List<ParameterBuilder>();
     this.Parameters.Add(new ParameterBuilder(null, 0));
     if (Parameters != null)
     {
         int x = 1;
         if (Name.StartsWith("set_"))
             x = -1;
         foreach (Type ParameterType in Parameters)
         {
             this.Parameters.Add(new ParameterBuilder(ParameterType, x));
             ++x;
         }
     }
     Commands = new List<ICommand>();
     Builder = Type.Builder.DefineMethod(Name, Attributes, ReturnType,
         (Parameters != null && Parameters.Count > 0) ? Parameters.ToArray() : System.Type.EmptyTypes);
     Generator = Builder.GetILGenerator();
 }
 public MethodBuilder(TypeBuilder TypeBuilder, string Name,
     MethodAttributes Attributes, IEnumerable<Type> Parameters, Type ReturnType)
     : base()
 {
     Contract.Requires<ArgumentNullException>(TypeBuilder!=null,"TypeBuilder");
     Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(Name),"Name");
     this.Name = Name;
     this.Type = TypeBuilder;
     this.Attributes = Attributes;
     this.ReturnType = (ReturnType == null) ? typeof(void) : ReturnType;
     this.Parameters = new List<ParameterBuilder>();
     this.Parameters.Add(new ParameterBuilder(null, 0));
     if (Parameters != null)
     {
         int x = 1;
         if (Name.StartsWith("set_", StringComparison.InvariantCulture))
             x = -1;
         foreach (Type ParameterType in Parameters)
         {
             this.Parameters.Add(new ParameterBuilder(ParameterType, x));
             ++x;
         }
     }
     Builder = Type.Builder.DefineMethod(Name, Attributes, ReturnType,
         (Parameters != null && Parameters.Count() > 0) ? Parameters.ToArray() : System.Type.EmptyTypes);
     Generator = Builder.GetILGenerator();
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="TypeBuilder">Type builder</param>
 /// <param name="Attributes">Attributes for the constructor (public, private, etc.)</param>
 public DefaultConstructorBuilder(TypeBuilder TypeBuilder, MethodAttributes Attributes)
     : base()
 {
     Contract.Requires<ArgumentNullException>(TypeBuilder!=null,"TypeBuilder");
     this.Type = TypeBuilder;
     this.Attributes = Attributes;
     this.Builder = Type.Builder.DefineDefaultConstructor(Attributes);
     this.Generator = null;
     this.Parameters = new List<ParameterBuilder>();
     this.Parameters.Add(new ParameterBuilder(null, 0));
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="TypeBuilder">Type builder</param>
 /// <param name="Attributes">Attributes for the constructor (public, private, etc.)</param>
 public DefaultConstructorBuilder(TypeBuilder TypeBuilder, MethodAttributes Attributes)
     : base()
 {
     if (TypeBuilder == null)
         throw new ArgumentNullException("TypeBuilder");
     this.Type = TypeBuilder;
     this.Attributes = Attributes;
     this.Builder = Type.Builder.DefineDefaultConstructor(Attributes);
     this.Generator = null;
     this.Parameters = new List<ParameterBuilder>();
     this.Parameters.Add(new ParameterBuilder(null, 0));
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="TypeBuilder">Type builder</param>
 /// <param name="Attributes">Attributes for the constructor (public, private, etc.)</param>
 /// <param name="Parameters">Parameter types for the constructor</param>
 /// <param name="CallingConventions">Calling convention for the constructor</param>
 public ConstructorBuilder(TypeBuilder TypeBuilder, MethodAttributes Attributes,
     IEnumerable<Type> Parameters, CallingConventions CallingConventions)
     : base()
 {
     Contract.Requires<ArgumentNullException>(TypeBuilder!=null,"TypeBuilder");
     this.Type = TypeBuilder;
     this.Attributes = Attributes;
     this.Parameters = new List<ParameterBuilder>();
     this.Parameters.Add(new ParameterBuilder(null, 0));
     if (Parameters != null)
     {
         int x = 1;
         foreach (Type ParameterType in Parameters)
         {
             this.Parameters.Add(new ParameterBuilder(ParameterType, x));
             ++x;
         }
     }
     this.CallingConventions = CallingConventions;
     this.Builder = Type.Builder.DefineConstructor(Attributes, CallingConventions,
         (Parameters != null && Parameters.Count() > 0) ? Parameters.ToArray() : System.Type.EmptyTypes);
     this.Generator = Builder.GetILGenerator();
 }
        /// <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());
            }
        }