public class Manager:Singleton<Manager>
{
protected Manager()
: base()
{
Configuration = Gestalt.Manager.Instance.GetConfigFile<Configuration>("AspectusConfiguration");
if (Configuration.AspectLocation.EndsWith(".dll",StringComparison.CurrentCultureIgnoreCase))
{
Assembly TempAssembly = Assembly.LoadFile(Configuration.AspectLocation);
Gestalt.Manager.Instance.RegisterConfigFile(TempAssembly);
DotExtension.Manager.Instance.Setup(TempAssembly);
}
else if (Utilities.IO.FileManager.DirectoryExists(Configuration.AspectLocation))
{
List<Assembly> Assemblies = Utilities.Reflection.Reflection.GetAssembliesFromDirectory(Configuration.AspectLocation, true);
foreach (Assembly Assembly in Assemblies)
{
Gestalt.Manager.Instance.RegisterConfigFile(Assembly);
DotExtension.Manager.Instance.Setup(Assembly);
}
}
else
{
Assembly TempAssembly = Assembly.Load(Configuration.AspectLocation);
Gestalt.Manager.Instance.RegisterConfigFile(TempAssembly);
DotExtension.Manager.Instance.Setup(TempAssembly);
}
Classes = new Dictionary<Type, Type>();
AssemblyName Name = new AssemblyName(Configuration.AssemblyName);
AppDomain Domain = Thread.GetDomain();
Builder = Domain.DefineDynamicAssembly(Name, AssemblyBuilderAccess.RunAndSave, Configuration.AssemblyDirectory);
Module = Builder.DefineDynamicModule(Configuration.AssemblyName, Configuration.AssemblyName + ".dll", true);
}
public void Save()
{
Builder.Save(Configuration.AssemblyName + ".dll");
}
public void Setup(Type Type)
{
List<Type> Interfaces = new List<Type>();
foreach (IAspect Extension in DotExtension.Manager.Instance.Extensions.OfType<IAspect>())
{
if (Extension.InterfacesUsing != null)
{
Interfaces.AddRange(Extension.InterfacesUsing);
}
}
Interfaces.Add(typeof(IEvents));
TypeBuilder TypeBuilder = Module.DefineType(Configuration.AssemblyName + "." + Type.Name + "Derived", TypeAttributes.Public, Type, Interfaces.ToArray());
MethodAttributes GetSetAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual;
CreateStartingEvent(TypeBuilder, GetSetAttributes);
CreateEndingEvent(TypeBuilder, GetSetAttributes);
CreateExceptionEvent(TypeBuilder, GetSetAttributes);
foreach (IAspect Extension in DotExtension.Manager.Instance.Extensions.OfType<IAspect>())
{
Extension.SetupInterfaces(TypeBuilder);
}
foreach (MethodInfo Method in Type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
{
if (Method.IsVirtual)
{
CreateMethod(Type, Method, TypeBuilder);
}
}
Classes.Add(Type, TypeBuilder.CreateType());
}
public T Create<T>()
{
T ReturnObject = (T)Classes[typeof(T)].Assembly.CreateInstance(Classes[typeof(T)].FullName);
foreach (IAspect Extension in DotExtension.Manager.Instance.Extensions.OfType<IAspect>())
{
Extension.Setup(ReturnObject);
}
return ReturnObject;
}
private void CreateMethod(Type Type, MethodInfo Method, TypeBuilder TypeBuilder)
{
MethodAttributes MethodAttribute = MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public;
if (Method.IsStatic)
MethodAttribute |= MethodAttributes.Static;
ParameterInfo[] Parameters = Method.GetParameters();
Type[] ParameterTypes = new Type[Parameters.Length];
int x = 0;
foreach (ParameterInfo Parameter in Parameters)
{
ParameterTypes[x] = Parameter.ParameterType;
++x;
}
MethodBuilder TempMethodBuilder = TypeBuilder.DefineMethod(Method.Name, MethodAttribute, Method.ReturnType, ParameterTypes);
ILGenerator MethodILGenerator = TempMethodBuilder.GetILGenerator();
LocalBuilder LocalReturn = null;
if (Method.ReturnType != typeof(void))
{
LocalReturn = MethodILGenerator.DeclareLocal(Method.ReturnType);
}
LocalBuilder StartingArgs = MethodILGenerator.DeclareLocal(typeof(Starting));
LocalBuilder EndingArgs = MethodILGenerator.DeclareLocal(typeof(Ending));
LocalBuilder ErrorArgs = MethodILGenerator.DeclareLocal(typeof(Aspectus.EventArgs.Exception));
Label MethodTryEndLabel = MethodILGenerator.DefineLabel();
MethodILGenerator.BeginExceptionBlock();
AddStartingBlock(MethodILGenerator, StartingArgs, Method, LocalReturn);
foreach (IAspect Extension in DotExtension.Manager.Instance.Extensions.OfType<IAspect>())
{
Extension.SetupStartMethod(MethodILGenerator, Method, Type);
}
if (!Method.IsStatic)
{
MethodILGenerator.Emit(OpCodes.Ldarg_0);
}
foreach (ParameterInfo Parameter in Parameters)
{
MethodILGenerator.Emit(OpCodes.Ldarg, Parameter.Position + (Method.IsStatic ? 0 : 1));
}
MethodILGenerator.EmitCall(OpCodes.Call, Method, new Type[0]);
if (Method.ReturnType != typeof(void))
{
MethodILGenerator.Emit(OpCodes.Stloc, LocalReturn.LocalIndex);
}
MethodILGenerator.Emit(OpCodes.Br_S, MethodTryEndLabel);
AddExceptionBlock(MethodILGenerator, Method, Type, ErrorArgs);
MethodILGenerator.MarkLabel(MethodTryEndLabel);
foreach (IAspect Extension in DotExtension.Manager.Instance.Extensions.OfType<IAspect>())
{
Extension.SetupEndMethod(MethodILGenerator, Method, Type, LocalReturn);
}
AddEndingBlock(MethodILGenerator, EndingArgs, Method, LocalReturn);
if (Method.ReturnType != typeof(void))
{
MethodILGenerator.Emit(OpCodes.Ldloc, LocalReturn.LocalIndex);
}
MethodILGenerator.Emit(OpCodes.Ret);
TypeBuilder.DefineMethodOverride(TempMethodBuilder, Method);
}
private void AddEndingBlock(ILGenerator Generator, LocalBuilder EndingArgs, MethodInfo Method,LocalBuilder LocalReturn)
{
Generator.Emit(OpCodes.Newobj, typeof(Ending).GetConstructor(new Type[0]));
Generator.Emit(OpCodes.Stloc, EndingArgs.LocalIndex);
Generator.Emit(OpCodes.Ldloc, EndingArgs.LocalIndex);
Generator.Emit(OpCodes.Ldstr, Method.Name);
Generator.EmitCall(OpCodes.Callvirt, typeof(Ending).GetProperty("MethodName").GetSetMethod(), null);
if (LocalReturn != null)
{
Generator.Emit(OpCodes.Ldloc, EndingArgs.LocalIndex);
Generator.Emit(OpCodes.Ldloc, LocalReturn.LocalIndex);
Generator.Emit(OpCodes.Box, LocalReturn.LocalType);
Generator.EmitCall(OpCodes.Callvirt, typeof(Ending).GetProperty("ReturnValue").GetSetMethod(), null);
}
ParameterInfo[] Parameters = Method.GetParameters();
foreach (ParameterInfo Parameter in Parameters)
{
Generator.Emit(OpCodes.Ldloc, EndingArgs.LocalIndex);
Generator.EmitCall(OpCodes.Callvirt, typeof(Ending).GetProperty("Parameters").GetGetMethod(), null);
Generator.Emit(OpCodes.Ldarg, Parameter.Position + (Method.IsStatic ? 0 : 1));
if (!Parameter.ParameterType.IsByRef)
{
Generator.Emit(OpCodes.Box, Parameter.ParameterType);
}
else
{
Generator.Emit(OpCodes.Box, typeof(int));
}
Generator.EmitCall(OpCodes.Callvirt, typeof(List<object>).GetMethod("Add"), null);
}
Generator.Emit(OpCodes.Nop);
Generator.Emit(OpCodes.Ldarg_0);
Generator.Emit(OpCodes.Castclass, typeof(IEvents));
Generator.EmitCall(OpCodes.Callvirt, typeof(IEvents).GetProperty("Aspectus_Ending").GetGetMethod(), null);
Generator.Emit(OpCodes.Ldarg_0);
Generator.Emit(OpCodes.Ldloc, EndingArgs.LocalIndex);
Type EventHelperType = typeof(Utilities.Events.EventHelper);
MethodInfo[] Methods = EventHelperType.GetMethods();
MethodInfo TempMethod = null;
foreach (MethodInfo TempMethodInfo in Methods)
{
if (TempMethodInfo.GetParameters().Length == 3)
{
TempMethod = TempMethodInfo;
break;
}
}
TempMethod = TempMethod.MakeGenericMethod(new Type[] { typeof(Ending) });
Generator.EmitCall(OpCodes.Call, TempMethod, null);
if (LocalReturn != null)
{
Label Equal = Generator.DefineLabel();
Generator.Emit(OpCodes.Ldloc, EndingArgs.LocalIndex);
Generator.EmitCall(OpCodes.Callvirt, typeof(Ending).GetProperty("ReturnValue").GetGetMethod(), null);
Generator.Emit(OpCodes.Ldnull);
Generator.Emit(OpCodes.Ceq);
Generator.Emit(OpCodes.Brtrue_S, Equal);
Generator.Emit(OpCodes.Ldloc, EndingArgs.LocalIndex);
Generator.EmitCall(OpCodes.Callvirt, typeof(Ending).GetProperty("ReturnValue").GetGetMethod(), null);
Generator.Emit(OpCodes.Unbox_Any, LocalReturn.LocalType);
Generator.Emit(OpCodes.Stloc, LocalReturn.LocalIndex);
Generator.MarkLabel(Equal);
}
}
private void AddExceptionBlock(ILGenerator Generator, MethodInfo MethodInfo, Type Type, LocalBuilder ErrorArgs)
{
Generator.BeginCatchBlock(typeof(System.Exception));
Generator.Emit(OpCodes.Stloc_0);
Generator.Emit(OpCodes.Newobj, typeof(Aspectus.EventArgs.Exception).GetConstructor(new Type[0]));
Generator.Emit(OpCodes.Stloc, ErrorArgs.LocalIndex);
Generator.Emit(OpCodes.Ldloc, ErrorArgs.LocalIndex);
Generator.Emit(OpCodes.Ldloc_0);
Generator.EmitCall(OpCodes.Callvirt, typeof(Aspectus.EventArgs.Exception).GetProperty("InternalException").GetSetMethod(), null);
Generator.Emit(OpCodes.Nop);
Generator.Emit(OpCodes.Ldarg_0);
Generator.Emit(OpCodes.Castclass, typeof(IEvents));
Generator.EmitCall(OpCodes.Callvirt, typeof(IEvents).GetProperty("Aspectus_Exception").GetGetMethod(), null);
Generator.Emit(OpCodes.Ldarg_0);
Generator.Emit(OpCodes.Ldloc, ErrorArgs.LocalIndex);
Type EventHelperType = typeof(Utilities.Events.EventHelper);
MethodInfo[] Methods = EventHelperType.GetMethods();
MethodInfo TempMethod = null;
foreach (MethodInfo Method in Methods)
{
if (Method.GetParameters().Length == 3)
{
TempMethod = Method;
break;
}
}
TempMethod = TempMethod.MakeGenericMethod(new Type[] { typeof(Aspectus.EventArgs.Exception) });
Generator.EmitCall(OpCodes.Call, TempMethod, null);
foreach (IAspect Extension in DotExtension.Manager.Instance.Extensions.OfType<IAspect>())
{
Extension.SetupExceptionMethod(Generator, MethodInfo, Type);
}
Generator.Emit(OpCodes.Rethrow);
Generator.EndExceptionBlock();
}
private void AddStartingBlock(ILGenerator Generator, LocalBuilder StartingArgs, MethodInfo Method,LocalBuilder LocalReturn)
{
Generator.Emit(OpCodes.Newobj, typeof(Starting).GetConstructor(new Type[0]));
Generator.Emit(OpCodes.Stloc, StartingArgs.LocalIndex);
Generator.Emit(OpCodes.Ldloc, StartingArgs.LocalIndex);
Generator.Emit(OpCodes.Ldstr, Method.Name);
Generator.EmitCall(OpCodes.Callvirt, typeof(Starting).GetProperty("MethodName").GetSetMethod(), null);
ParameterInfo[] Parameters = Method.GetParameters();
foreach (ParameterInfo Parameter in Parameters)
{
Generator.Emit(OpCodes.Ldloc, StartingArgs.LocalIndex);
Generator.EmitCall(OpCodes.Callvirt, typeof(Starting).GetProperty("Parameters").GetGetMethod(), null);
Generator.Emit(OpCodes.Ldarg, Parameter.Position + (Method.IsStatic ? 0 : 1));
if (!Parameter.ParameterType.IsByRef)
{
Generator.Emit(OpCodes.Box, Parameter.ParameterType);
}
else
{
Generator.Emit(OpCodes.Box, typeof(int));
}
Generator.EmitCall(OpCodes.Callvirt, typeof(List<object>).GetMethod("Add"), null);
}
Generator.Emit(OpCodes.Ldarg_0);
Generator.Emit(OpCodes.Castclass, typeof(IEvents));
Generator.EmitCall(OpCodes.Callvirt, typeof(IEvents).GetProperty("Aspectus_Starting").GetGetMethod(), null);
Generator.Emit(OpCodes.Ldarg_0);
Generator.Emit(OpCodes.Ldloc, StartingArgs.LocalIndex);
Type EventHelperType = typeof(Utilities.Events.EventHelper);
MethodInfo[] Methods = EventHelperType.GetMethods();
MethodInfo TempMethod = null;
foreach (MethodInfo TempMethodInfo in Methods)
{
if (TempMethodInfo.GetParameters().Length == 3)
{
TempMethod = TempMethodInfo;
break;
}
}
TempMethod = TempMethod.MakeGenericMethod(new Type[] { typeof(Starting) });
Generator.EmitCall(OpCodes.Call, TempMethod, null);
if (LocalReturn != null)
{
Label Equal = Generator.DefineLabel();
Generator.Emit(OpCodes.Ldloc, StartingArgs.LocalIndex);
Generator.EmitCall(OpCodes.Callvirt, typeof(Starting).GetProperty("ReturnValue").GetGetMethod(), null);
Generator.Emit(OpCodes.Ldnull);
Generator.Emit(OpCodes.Ceq);
Generator.Emit(OpCodes.Brtrue_S, Equal);
Generator.Emit(OpCodes.Ldloc, StartingArgs.LocalIndex);
Generator.EmitCall(OpCodes.Callvirt, typeof(Starting).GetProperty("ReturnValue").GetGetMethod(), null);
Generator.Emit(OpCodes.Unbox_Any, LocalReturn.LocalType);
Generator.Emit(OpCodes.Stloc, LocalReturn.LocalIndex);
Generator.Emit(OpCodes.Ldloc, LocalReturn.LocalIndex);
Generator.Emit(OpCodes.Ret);
Generator.MarkLabel(Equal);
}
}
private void CreateStartingEvent(TypeBuilder TypeBuilder, MethodAttributes GetSetAttributes)
{
FieldBuilder FieldBuilder = TypeBuilder.DefineField("_Aspectus_Starting", typeof(EventHandler<Starting>), FieldAttributes.Private);
PropertyBuilder PropertyBuilder = TypeBuilder.DefineProperty("Aspectus_Starting", PropertyAttributes.SpecialName,
typeof(EventHandler<Starting>), null);
MethodBuilder ValuePropertyGet = TypeBuilder.DefineMethod("get_Aspectus_Starting", GetSetAttributes,
typeof(EventHandler<Starting>), Type.EmptyTypes);
ILGenerator GetGenerator = ValuePropertyGet.GetILGenerator();
GetGenerator.Emit(OpCodes.Ldarg_0);
GetGenerator.Emit(OpCodes.Ldfld, FieldBuilder);
GetGenerator.Emit(OpCodes.Ret);
PropertyBuilder.SetGetMethod(ValuePropertyGet);
MethodBuilder ValuePropertySet = TypeBuilder.DefineMethod("set_Aspectus_Starting", GetSetAttributes, null,
new Type[] { typeof(EventHandler<Starting>) });
ILGenerator SetGenerator = ValuePropertySet.GetILGenerator();
SetGenerator.Emit(OpCodes.Ldarg_0);
SetGenerator.Emit(OpCodes.Ldarg_1);
SetGenerator.Emit(OpCodes.Stfld, FieldBuilder);
SetGenerator.Emit(OpCodes.Ret);
PropertyBuilder.SetSetMethod(ValuePropertySet);
}
private void CreateEndingEvent(TypeBuilder TypeBuilder, MethodAttributes GetSetAttributes)
{
FieldBuilder FieldBuilder = TypeBuilder.DefineField("_Aspectus_Ending", typeof(EventHandler<Ending>), FieldAttributes.Private);
PropertyBuilder PropertyBuilder = TypeBuilder.DefineProperty("Aspectus_Ending", PropertyAttributes.SpecialName,
typeof(EventHandler<Ending>), null);
MethodBuilder ValuePropertyGet = TypeBuilder.DefineMethod("get_Aspectus_Ending", GetSetAttributes,
typeof(EventHandler<Ending>), Type.EmptyTypes);
ILGenerator GetGenerator = ValuePropertyGet.GetILGenerator();
GetGenerator.Emit(OpCodes.Ldarg_0);
GetGenerator.Emit(OpCodes.Ldfld, FieldBuilder);
GetGenerator.Emit(OpCodes.Ret);
PropertyBuilder.SetGetMethod(ValuePropertyGet);
MethodBuilder ValuePropertySet = TypeBuilder.DefineMethod("set_Aspectus_Ending", GetSetAttributes, null,
new Type[] { typeof(EventHandler<Ending>) });
ILGenerator SetGenerator = ValuePropertySet.GetILGenerator();
SetGenerator.Emit(OpCodes.Ldarg_0);
SetGenerator.Emit(OpCodes.Ldarg_1);
SetGenerator.Emit(OpCodes.Stfld, FieldBuilder);
SetGenerator.Emit(OpCodes.Ret);
PropertyBuilder.SetSetMethod(ValuePropertySet);
}
private void CreateExceptionEvent(TypeBuilder TypeBuilder, MethodAttributes GetSetAttributes)
{
FieldBuilder FieldBuilder = TypeBuilder.DefineField("_Aspectus_Exception", typeof(EventHandler<Aspectus.EventArgs.Exception>), FieldAttributes.Private);
PropertyBuilder PropertyBuilder = TypeBuilder.DefineProperty("Aspectus_Exception", PropertyAttributes.SpecialName,
typeof(EventHandler<Aspectus.EventArgs.Exception>), null);
MethodBuilder ValuePropertyGet = TypeBuilder.DefineMethod("get_Aspectus_Exception", GetSetAttributes,
typeof(EventHandler<Aspectus.EventArgs.Exception>), Type.EmptyTypes);
ILGenerator GetGenerator = ValuePropertyGet.GetILGenerator();
GetGenerator.Emit(OpCodes.Ldarg_0);
GetGenerator.Emit(OpCodes.Ldfld, FieldBuilder);
GetGenerator.Emit(OpCodes.Ret);
PropertyBuilder.SetGetMethod(ValuePropertyGet);
MethodBuilder ValuePropertySet = TypeBuilder.DefineMethod("set_Aspectus_Exception", GetSetAttributes, null,
new Type[] { typeof(EventHandler<Aspectus.EventArgs.Exception>) });
ILGenerator SetGenerator = ValuePropertySet.GetILGenerator();
SetGenerator.Emit(OpCodes.Ldarg_0);
SetGenerator.Emit(OpCodes.Ldarg_1);
SetGenerator.Emit(OpCodes.Stfld, FieldBuilder);
SetGenerator.Emit(OpCodes.Ret);
PropertyBuilder.SetSetMethod(ValuePropertySet);
}
protected AssemblyBuilder Builder { get; set; }
protected ModuleBuilder Module { get; set; }
protected Dictionary<Type, Type> Classes { get; set; }
protected Configuration Configuration { get; set; }
}