|
|
@@ -3,8 +3,6 @@ using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Reflection;
|
|
|
using System.Reflection.Emit;
|
|
|
-using System.Text;
|
|
|
-using System.Threading.Tasks;
|
|
|
|
|
|
namespace WCS.Core
|
|
|
{
|
|
|
@@ -15,8 +13,9 @@ namespace WCS.Core
|
|
|
/// <typeparam name="TBase">基类</typeparam>
|
|
|
public static class Generator<T, TBase> where TBase : IProtocolProxy
|
|
|
{
|
|
|
- static TypeBuilder tb;
|
|
|
- static Type Type;
|
|
|
+ private static TypeBuilder tb;
|
|
|
+ private static Type Type;
|
|
|
+
|
|
|
static Generator()
|
|
|
{
|
|
|
if (!typeof(T).IsInterface)
|
|
|
@@ -29,20 +28,18 @@ namespace WCS.Core
|
|
|
AssemblyBuilder myAssembly = AssemblyBuilder.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.RunAndCollect);
|
|
|
//AssemblyBuilder myAssembly = AssemblyBuilder.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.RunAndSave);
|
|
|
|
|
|
-
|
|
|
ModuleBuilder myModule = myAssembly.DefineDynamicModule("Main");
|
|
|
tb = myModule.DefineType(typeof(T).Name + "_Generate", TypeAttributes.Public, typeof(TBase), new Type[] { typeof(T) });
|
|
|
InitConstructors();
|
|
|
InitMethods();
|
|
|
InitProperties();
|
|
|
- InitEvents();
|
|
|
+ InitEvents();
|
|
|
try
|
|
|
{
|
|
|
Type = tb.CreateTypeInfo().AsType();//.CreateType();
|
|
|
}
|
|
|
- catch (Exception ex)
|
|
|
+ catch (Exception)
|
|
|
{
|
|
|
-
|
|
|
}
|
|
|
//myAssembly.Save(typeof(T).Name + ".dll");
|
|
|
}
|
|
|
@@ -50,9 +47,8 @@ namespace WCS.Core
|
|
|
private const MethodAttributes METHOD_ATTRIBUTES =
|
|
|
MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig;
|
|
|
|
|
|
- static void InitConstructors()
|
|
|
+ private static void InitConstructors()
|
|
|
{
|
|
|
-
|
|
|
foreach (var cons in typeof(TBase).GetConstructors())
|
|
|
{
|
|
|
var pTypes = cons.GetParameters().Select(v => v.ParameterType).ToArray();
|
|
|
@@ -72,7 +68,8 @@ namespace WCS.Core
|
|
|
il.Emit(OpCodes.Ret);
|
|
|
}
|
|
|
}
|
|
|
- static void InitMethods()
|
|
|
+
|
|
|
+ private static void InitMethods()
|
|
|
{
|
|
|
var ms = GetInterfaces().SelectMany(v => v.GetMethods()).ToArray();
|
|
|
ms = ms.Where(v => !v.IsSpecialName).ToArray();
|
|
|
@@ -81,7 +78,8 @@ namespace WCS.Core
|
|
|
GenerateMethod(m);
|
|
|
}
|
|
|
}
|
|
|
- static void InitProperties()
|
|
|
+
|
|
|
+ private static void InitProperties()
|
|
|
{
|
|
|
var ps = GetInterfaces().SelectMany(v => v.GetProperties());
|
|
|
ps = GetMembers().OfType<PropertyInfo>();
|
|
|
@@ -121,7 +119,8 @@ namespace WCS.Core
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- static void InitEvents()
|
|
|
+
|
|
|
+ private static void InitEvents()
|
|
|
{
|
|
|
var evts = GetInterfaces().SelectMany(v => v.GetEvents());
|
|
|
|
|
|
@@ -134,26 +133,24 @@ namespace WCS.Core
|
|
|
eb.SetRemoveOnMethod(remove);
|
|
|
}
|
|
|
}
|
|
|
- static MethodBuilder GenerateMethod(MethodInfo m)
|
|
|
- {
|
|
|
|
|
|
+ private static MethodBuilder GenerateMethod(MethodInfo m)
|
|
|
+ {
|
|
|
var pTypes = m.GetParameters().Select(v => v.ParameterType).ToArray();
|
|
|
var mb = tb.DefineMethod(m.Name, METHOD_ATTRIBUTES, CallingConventions.Standard, m.ReturnType, pTypes);
|
|
|
var ilGen = mb.GetILGenerator();
|
|
|
|
|
|
-
|
|
|
- ilGen.DeclareLocal(typeof(object[]));//声明object数组变量
|
|
|
+ ilGen.DeclareLocal(typeof(object[]));//声明object数组变量
|
|
|
|
|
|
#region 参数准备
|
|
|
- ilGen.Emit(OpCodes.Ldarg_0); //this
|
|
|
- ilGen.Emit(OpCodes.Ldstr,m.Name); //string name
|
|
|
|
|
|
+ ilGen.Emit(OpCodes.Ldarg_0); //this
|
|
|
+ ilGen.Emit(OpCodes.Ldstr, m.Name); //string name
|
|
|
|
|
|
ilGen.Emit(OpCodes.Ldc_I4_S, pTypes.Length);//数组长度
|
|
|
ilGen.Emit(OpCodes.Newarr, typeof(object));//数组
|
|
|
ilGen.Emit(OpCodes.Stloc_0);
|
|
|
|
|
|
-
|
|
|
for (int i = 0; i < pTypes.Length; i++)
|
|
|
{
|
|
|
ilGen.Emit(OpCodes.Ldloc_0);
|
|
|
@@ -162,17 +159,19 @@ namespace WCS.Core
|
|
|
ilGen.Emit(OpCodes.Box, pTypes[i]);
|
|
|
ilGen.Emit(OpCodes.Stelem_Ref);
|
|
|
}
|
|
|
- #endregion
|
|
|
+
|
|
|
+ #endregion 参数准备
|
|
|
+
|
|
|
ilGen.Emit(OpCodes.Ldloc_0);
|
|
|
|
|
|
if (m.ReturnType != typeof(void))
|
|
|
{
|
|
|
var mi = typeof(TBase).GetMethod("CallReturn", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
|
|
|
mi = mi.MakeGenericMethod(m.ReturnType);
|
|
|
- ilGen.Emit(OpCodes.Call, mi);
|
|
|
+ ilGen.Emit(OpCodes.Call, mi);
|
|
|
LocalBuilder local = ilGen.DeclareLocal(m.ReturnType);
|
|
|
ilGen.Emit(OpCodes.Stloc_1, local);
|
|
|
- ilGen.Emit(OpCodes.Ldloc_1, local);
|
|
|
+ ilGen.Emit(OpCodes.Ldloc_1, local);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -182,25 +181,26 @@ namespace WCS.Core
|
|
|
ilGen.Emit(OpCodes.Ret);
|
|
|
return mb;
|
|
|
}
|
|
|
- static MethodBuilder GenerateProperty(MethodInfo m)
|
|
|
+
|
|
|
+ private static MethodBuilder GenerateProperty(MethodInfo m)
|
|
|
{
|
|
|
var pTypes = m.GetParameters().Select(v => v.ParameterType).ToArray();
|
|
|
var mb = tb.DefineMethod(m.Name, METHOD_ATTRIBUTES, CallingConventions.Standard, m.ReturnType, pTypes);
|
|
|
- var ilGen = mb.GetILGenerator();
|
|
|
-
|
|
|
+ var ilGen = mb.GetILGenerator();
|
|
|
|
|
|
#region 参数准备
|
|
|
+
|
|
|
ilGen.Emit(OpCodes.Ldarg_0); //this
|
|
|
- ilGen.Emit(OpCodes.Ldstr, m.Name.Replace("set_", "").Replace("get_", "")); //string name
|
|
|
+ ilGen.Emit(OpCodes.Ldstr, m.Name.Replace("set_", "").Replace("get_", "")); //string name
|
|
|
|
|
|
- #endregion
|
|
|
+ #endregion 参数准备
|
|
|
|
|
|
if (m.Name.StartsWith("set_"))
|
|
|
{
|
|
|
- ilGen.Emit(OpCodes.Ldarg_1);//value 准备参数
|
|
|
+ ilGen.Emit(OpCodes.Ldarg_1);//value 准备参数
|
|
|
var mi = typeof(TBase).GetMethod("Set", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
|
mi = mi.MakeGenericMethod(pTypes);
|
|
|
- ilGen.Emit(OpCodes.Call, mi); //调用基类方法
|
|
|
+ ilGen.Emit(OpCodes.Call, mi); //调用基类方法
|
|
|
//ilGen.Emit(OpCodes.Pop);
|
|
|
}
|
|
|
else
|
|
|
@@ -209,35 +209,34 @@ namespace WCS.Core
|
|
|
mi = mi.MakeGenericMethod(m.ReturnType);
|
|
|
ilGen.Emit(OpCodes.Call, mi);//调用方法
|
|
|
|
|
|
- #region 返回值
|
|
|
+ #region 返回值
|
|
|
|
|
|
LocalBuilder local = ilGen.DeclareLocal(m.ReturnType);
|
|
|
ilGen.Emit(OpCodes.Stloc_0, local);
|
|
|
- ilGen.Emit(OpCodes.Ldloc_0, local);
|
|
|
-
|
|
|
- #endregion
|
|
|
+ ilGen.Emit(OpCodes.Ldloc_0, local);
|
|
|
+
|
|
|
+ #endregion 返回值
|
|
|
}
|
|
|
ilGen.Emit(OpCodes.Ret);//return
|
|
|
return mb;
|
|
|
}
|
|
|
|
|
|
- static MethodBuilder GenerateIndexer(MethodInfo m)
|
|
|
+ private static MethodBuilder GenerateIndexer(MethodInfo m)
|
|
|
{
|
|
|
var pTypes = m.GetParameters().Select(v => v.ParameterType).ToArray();
|
|
|
var mb = tb.DefineMethod(m.Name, METHOD_ATTRIBUTES, CallingConventions.Standard, m.ReturnType, pTypes);
|
|
|
var ilGen = mb.GetILGenerator();
|
|
|
|
|
|
-
|
|
|
#region 参数准备
|
|
|
- ilGen.DeclareLocal(typeof(object[]));//声明object数组变量
|
|
|
|
|
|
- ilGen.Emit(OpCodes.Ldarg_0); //this
|
|
|
+ ilGen.DeclareLocal(typeof(object[]));//声明object数组变量
|
|
|
+
|
|
|
+ ilGen.Emit(OpCodes.Ldarg_0); //this
|
|
|
|
|
|
ilGen.Emit(OpCodes.Ldc_I4_S, pTypes.Length);//数组长度
|
|
|
ilGen.Emit(OpCodes.Newarr, typeof(object));//数组
|
|
|
ilGen.Emit(OpCodes.Stloc_0);
|
|
|
|
|
|
-
|
|
|
int i = 0;
|
|
|
for (i = 0; i < pTypes.Length; i++)
|
|
|
{
|
|
|
@@ -247,15 +246,16 @@ namespace WCS.Core
|
|
|
ilGen.Emit(OpCodes.Box, pTypes[i]);
|
|
|
ilGen.Emit(OpCodes.Stelem_Ref);
|
|
|
}
|
|
|
- #endregion
|
|
|
+
|
|
|
+ #endregion 参数准备
|
|
|
|
|
|
ilGen.Emit(OpCodes.Ldloc_0);
|
|
|
|
|
|
if (m.Name.StartsWith("set"))
|
|
|
{
|
|
|
- //ilGen.Emit(OpCodes.Ldarg_S, 1 + i);//value 准备参数
|
|
|
- var mi = typeof(TBase).GetMethod("SetItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
|
- ilGen.Emit(OpCodes.Call, mi); //调用基类方法
|
|
|
+ //ilGen.Emit(OpCodes.Ldarg_S, 1 + i);//value 准备参数
|
|
|
+ var mi = typeof(TBase).GetMethod("SetItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
|
+ ilGen.Emit(OpCodes.Call, mi); //调用基类方法
|
|
|
//ilGen.Emit(OpCodes.Pop);
|
|
|
}
|
|
|
else
|
|
|
@@ -264,19 +264,19 @@ namespace WCS.Core
|
|
|
mi = mi.MakeGenericMethod(m.ReturnType);
|
|
|
ilGen.Emit(OpCodes.Call, mi);//调用方法
|
|
|
|
|
|
- #region 返回值
|
|
|
+ #region 返回值
|
|
|
|
|
|
LocalBuilder local = ilGen.DeclareLocal(m.ReturnType);
|
|
|
ilGen.Emit(OpCodes.Stloc_1, local);
|
|
|
ilGen.Emit(OpCodes.Ldloc_1, local);
|
|
|
|
|
|
- #endregion
|
|
|
+ #endregion 返回值
|
|
|
}
|
|
|
ilGen.Emit(OpCodes.Ret);//return
|
|
|
return mb;
|
|
|
}
|
|
|
|
|
|
- static MethodBuilder GenerateEventEnabled(EventInfo evt, MethodInfo m)
|
|
|
+ private static MethodBuilder GenerateEventEnabled(EventInfo evt, MethodInfo m)
|
|
|
{
|
|
|
bool add = m.Name.StartsWith("add_");
|
|
|
var n = m.DeclaringType.Name;
|
|
|
@@ -284,7 +284,6 @@ namespace WCS.Core
|
|
|
var mb = tb.DefineMethod(m.Name, METHOD_ATTRIBUTES, CallingConventions.Standard, m.ReturnType, pTypes);
|
|
|
var ilGen = mb.GetILGenerator();
|
|
|
|
|
|
-
|
|
|
//ilGen.DeclareLocal(typeof(EventInfo));//声明字符串变量
|
|
|
//ilGen.DeclareLocal(typeof(Delegate)); //value Delegate
|
|
|
|
|
|
@@ -293,42 +292,43 @@ namespace WCS.Core
|
|
|
//ilGen.Emit(OpCodes.Ldarg_1);//Delegate dlg
|
|
|
//ilGen.Emit(OpCodes.Stloc_1);//保存至变量
|
|
|
|
|
|
-
|
|
|
-
|
|
|
#region 参数准备
|
|
|
+
|
|
|
ilGen.Emit(OpCodes.Ldarg_0);
|
|
|
- ilGen.Emit(OpCodes.Ldstr,evt.Name);
|
|
|
+ ilGen.Emit(OpCodes.Ldstr, evt.Name);
|
|
|
ilGen.Emit(OpCodes.Ldarg_1);
|
|
|
|
|
|
- #endregion
|
|
|
- var mname = add ? "AddEvent" :"RemoveEvent";
|
|
|
+ #endregion 参数准备
|
|
|
+
|
|
|
+ var mname = add ? "AddEvent" : "RemoveEvent";
|
|
|
ilGen.Emit(OpCodes.Call, typeof(TBase).GetMethod(mname, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
|
|
|
|
|
|
ilGen.Emit(OpCodes.Ret);
|
|
|
return mb;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- static Type[] GetInterfaces()
|
|
|
+ private static Type[] GetInterfaces()
|
|
|
{
|
|
|
var tInterface = typeof(T);
|
|
|
var ts = tInterface.GetInterfaces().ToList();
|
|
|
ts.Add(tInterface);
|
|
|
return ts.ToArray();
|
|
|
}
|
|
|
- static MemberInfo[] GetMembers()
|
|
|
+
|
|
|
+ private static MemberInfo[] GetMembers()
|
|
|
{
|
|
|
var members = GetInterfaces().SelectMany(v => v.GetMembers()).Distinct().ToArray();
|
|
|
return members;
|
|
|
}
|
|
|
+
|
|
|
public static T Create(params object[] args)
|
|
|
{
|
|
|
return (T)Activator.CreateInstance(Type, args);
|
|
|
}
|
|
|
+
|
|
|
public static Type GetGenerateType()
|
|
|
{
|
|
|
return Type;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|