diff --git a/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/NatashaSlimMethodBuilder.cs b/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/NatashaSlimMethodBuilder.cs new file mode 100644 index 00000000..1ebdbcbc --- /dev/null +++ b/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/NatashaSlimMethodBuilder.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Natasha.CSharp.Extension.MethodCreator +{ + public class NatashaSlimMethodBuilder + { + public readonly AssemblyCSharpBuilder Builder; + public readonly string Script; + public readonly HashSet Usings; + public object[]? PrivateObjects; + private Action? _ctxConfig; + private Action? _builderConfig; + public NatashaSlimMethodBuilder(string script) + { + Usings = []; + Builder = new AssemblyCSharpBuilder(); + Script = script; + } + public NatashaSlimMethodBuilder WithPrivateAccess(params object[] objs) + { + PrivateObjects = objs; + return this; + } + + public NatashaSlimMethodBuilder ConfigBuilder(Action config) + { + _builderConfig = config; + return this; + } + public NatashaSlimMethodBuilder ConfigBuilder(Action config) + { + _ctxConfig = config; + return this; + } + public NatashaSlimMethodBuilder WithSimpleBuilder() + { + Builder.UseRandomLoadContext(); + Builder.UseSimpleMode(); + Builder.ConfigLoadContext(ctx => ctx.AddReferenceAndUsingCode()); + return this; + } + + public NatashaSlimMethodBuilder WithUsings(params string[] usings) + { + Usings.UnionWith(usings); + return this; + } + + public NatashaSlimMethodBuilder WithMetadata() + { + Builder.ConfigLoadContext(ctx => ctx.AddReferenceAndUsingCode()); + return this; + } + + public NatashaSlimMethodBuilder WithMetadata(params Type[] types) + { + if (types!=null && types.Length > 0) + { + foreach (var type in types) + { + Builder.ConfigLoadContext(ctx => ctx.AddReferenceAndUsingCode(type)); + } + } + return this; + } + + public T ToDelegate(string modifier = "") where T : Delegate + { + _builderConfig?.Invoke(Builder); + _ctxConfig?.Invoke(Builder.LoadContext); + + var className = $"N{Guid.NewGuid():N}"; + var methodInfo = typeof(T).GetMethod("Invoke")!; + + var returnTypeScript = methodInfo.ReturnType.GetDevelopName(); + var parameterScript = new StringBuilder(); + + var methodParameters = methodInfo.GetParameters(); + for (int i = 0; i < methodParameters.Length; i += 1) + { + var paramType = methodParameters[i].ParameterType; + Builder.ConfigLoadContext(ctx => ctx.AddReferenceAndUsingCode(paramType)); + parameterScript.Append($"{paramType.GetDevelopName()} arg{i + 1},"); + } + if (parameterScript.Length > 0) + { + parameterScript.Length -= 1; + } + + StringBuilder usingCode = new(); + foreach (var item in Usings) + { + + usingCode.AppendLine($"using {item};"); + + } + var fullScript = $"{usingCode} public static class {className} {{ public static {(modifier ?? string.Empty)} {returnTypeScript} Invoke({parameterScript}){{ {Script} }} }}"; + if (PrivateObjects!=null) + { + Builder.Add(fullScript.ToAccessPrivateTree(PrivateObjects)); + } + else + { + Builder.Add(fullScript); + } + var asm = Builder.GetAssembly(); + var type = asm.GetType(className); + if (type != null) + { + return (T)Delegate.CreateDelegate(typeof(T), type.GetMethod("Invoke")!); + } + throw new Exception($"未找到 {className} 类型!"); + } + public T ToAsyncDelegate() where T : Delegate + { + return ToDelegate("async"); + } + public T ToUnsafeDelegate() where T : Delegate + { + return ToDelegate("unsafe"); + } + public T ToUnsafeAsyncDelegate() where T : Delegate + { + return ToDelegate("unsafe async"); + } + } +} diff --git a/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/StringExtension.cs b/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/StringExtension.cs index af9fe5fb..5721004c 100644 --- a/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/StringExtension.cs +++ b/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/StringExtension.cs @@ -1,4 +1,5 @@ -using System; +using Natasha.CSharp.Extension.MethodCreator; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; @@ -6,90 +7,25 @@ public static class StringExtension { - public static (string script, string[] usings, AssemblyCSharpBuilder builder) WithAssemblyBuilder(this string script, Func config) + public static NatashaSlimMethodBuilder WithSlimMethodBuilder(this string script, Action config) { - AssemblyCSharpBuilder builder = new(); - config?.Invoke(builder); - return (script, [], builder); + var builder = new NatashaSlimMethodBuilder(script); + builder.ConfigBuilder(config); + return builder; } - - public static (string script, string[] usings, AssemblyCSharpBuilder builder) WithAssemblyBuilder(this string script, Func config) - { - AssemblyCSharpBuilder builder = new(); - builder.ConfigLoadContext(config); - return (script, [], builder); - } - - public static (string script, string[] usings, AssemblyCSharpBuilder builder) WithSimpleBuilder(this string script) - { - AssemblyCSharpBuilder builder = new(); - builder.UseRandomLoadContext(); - builder.UseSimpleMode(); - builder.ConfigLoadContext(ctx => ctx.AddReferenceAndUsingCode()); - return (script, [], builder); - } - - public static (string script, string[] usings, AssemblyCSharpBuilder builder) WithMetadata(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) - { - return (buildInfo.script, buildInfo.usings, buildInfo.builder.ConfigLoadContext(ctx => ctx.AddReferenceAndUsingCode(typeof(T)))); - } - public static (string script, string[] usings, AssemblyCSharpBuilder builder) WithMetadata(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo, Type type) + public static NatashaSlimMethodBuilder WithSlimMethodBuilder(this string script, Action config) { - return (buildInfo.script, buildInfo.usings, buildInfo.builder.ConfigLoadContext(ctx => ctx.AddReferenceAndUsingCode(type))); + var builder = new NatashaSlimMethodBuilder(script); + builder.ConfigBuilder(config); + return builder; } - public static (string script, string[] usings, AssemblyCSharpBuilder builder) WithUsings(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo,params string[] usings) - { - return (buildInfo.script, usings, buildInfo.builder); - } - public static T ToDelegate(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo, string modifier = "") where T: Delegate - { - var scriptBuilder = buildInfo.builder; - var className = $"N{Guid.NewGuid():N}"; - var methodInfo = typeof(T).GetMethod("Invoke")!; - var returnTypeScript = methodInfo.ReturnType.GetDevelopName(); - var parameterScript = new StringBuilder(); - - var methodParameters = methodInfo.GetParameters(); - for (int i = 0; i < methodParameters.Length; i+=1) - { - var paramType = methodParameters[i].ParameterType; - scriptBuilder.ConfigLoadContext(ctx => ctx.AddReferenceAndUsingCode(paramType)); - parameterScript.Append($"{paramType.GetDevelopName()} arg{i+1},"); - } - if (parameterScript.Length > 0) - { - parameterScript.Length -= 1; - } - - StringBuilder usingCode = new(); - foreach (var item in buildInfo.usings) - { - - usingCode.AppendLine($"using {item};"); - - } - buildInfo.builder.Add($"{usingCode} public static class {className} {{ public static {(modifier ?? string.Empty)} {returnTypeScript} Invoke({parameterScript}){{ {buildInfo.script} }} }}"); - var asm = buildInfo.builder.GetAssembly(); - var type = asm.GetType(className); - if (type != null) - { - return (T)Delegate.CreateDelegate(typeof(T), type.GetMethod("Invoke")!); - } - throw new Exception($"未找到 {className} 类型!"); - } - public static T ToAsyncDelegate(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) where T : Delegate - { - return ToDelegate(buildInfo, "async"); - } - public static T ToUnsafeDelegate(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) where T : Delegate - { - return ToDelegate(buildInfo, "unsafe"); - } - public static T ToUnsafeAsyncDelegate(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) where T : Delegate + public static NatashaSlimMethodBuilder WithSlimMethodBuilder(this string script) { - return ToDelegate(buildInfo, "unsafe async"); + var builder = new NatashaSlimMethodBuilder(script); + builder.WithSimpleBuilder(); + return builder; } } diff --git a/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/SystemDelegateExtension.cs b/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/SystemDelegateExtension.cs index e02570ab..3c85bd8a 100644 --- a/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/SystemDelegateExtension.cs +++ b/src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/SystemDelegateExtension.cs @@ -1,108 +1,110 @@  +using Natasha.CSharp.Extension.MethodCreator; + namespace System { public static class SystemDelegateExtension { #region Action Delegate - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Action ToAction(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Action ToAction(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } #endregion #region Func Delegate - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } - public static Func ToFunc(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) + public static Func ToFunc(this NatashaSlimMethodBuilder builder) { - return buildInfo.ToDelegate>(); + return builder.ToDelegate>(); } #endregion