Open NMSAzulX opened 3 months ago
编号 | 相似度 | ISSUE |
---|---|---|
1 | 78.33% | [Tasks]: 有关【动态方法模板】相关功能的规划与任务细化 (意见搜集与讨论) |
2 | 73.03% | [Tasks]: 有关【UT IS DEMO】相关功能的规划与任务细化 (意见搜集与讨论) |
3 | 69.63% | [Tasks]: 有关【可视化管道配置】相关功能的规划与任务细化 (意见搜集与讨论) |
4 | 66.67% | [Tasks]: 有关【新版 NMS.Github.SDK】相关功能的规划与任务细化 (意见搜集与讨论) |
5 | 40.82% | [Next]: Natasha 的 【动态方法使用率】 相关功能建议搜集 |
该条自动推荐信息来自于 nms-bot.
轻量重载
依赖重建
理论支持 std2.0/2.1. 实际受 DotNetCore.Natasha.CSharp.Compiler.Domain 包版本限制. 除非自实现 DotNetCore.Natasha.DynamicLoad.Base 包。
class Program
{
public static void Main(string[] args)
{
//设置当前程序的类型 ,默认为 console
HEProxy.SetProjectKind(HEProjectKind.Console);
//创建热执行的日志输出实例
HEFileLogger logger = new HEFileLogger(debugFilePath);
//设置信息输出方式
HEProxy.ShowMessage = async msg => {
await logger.WriteUtf8FileAsync(msg);
};
//设置 Natasha 需要排除的 程序集
HEProxy.ExcludeGlobalUsing("System.Windows.Controls");
//HE:Debug (当前热编译环境指向为 Debug 编译,可以不写,默认为 Debug)
//编译初始化选项,主要是 Natasha 的初始化操作.
//Once (热编译时使用 Once 剔除该语句,不写也没关系)
HEProxy.SetCompileInitAction(()=>{{
NatashaManagement.RegistDomainCreator<NatashaDomainCreator>();
NatashaManagement.Preheating((asmName, @namespace) =>
!string.IsNullOrWhiteSpace(@namespace) &&
(@namespace.StartsWith(""Microsoft.VisualBasic"") ||
HEProxy.IsExcluded(@namespace)),
true,
true);
}});
//开始执行动态代理.
//Once (热编译时使用 Once 剔除该语句,不写也没关系)
HEProxy.Run();
for (int i = 0; i < args.Length; i++)
{
Console.WriteLine(args[i]);
}
//Once (这句 `//Once` 必须写,防止热编译是被 `Console.ReadKey()` 阻塞)
Console.ReadKey();
}
//方法体中的参数操作对应 Main(string[] args) 中的 args,
//热执行时,Main 将接收到 "参数11",“参数2”,“参数23”
//非必要,可以不写
public static void ProxyMainArguments()
{
ProjectDynamicProxy.AppendArgs("参数11");
ProjectDynamicProxy.AppendArgs("参数2");
ProjectDynamicProxy.AppendArgs("参数23");
}
}
.NET5.0 及以上版本适用, 案例中省略了 ProxyMainArguments 方法
class Program
{
//Console
public static void Main(string[] args)
{
//HE:Debug (当前热编译环境指向为 Debug 编译,可以不写,默认为 Debug)
for (int i = 0; i < args.Length; i++)
{
//下面这句 DS 注释在热编译中起到了输出的作用,可以代替 Console.WriteLine(args[i]);
//输出方式可以通过 HEProxy.ShowMessage = async msg => {} 进行设置.
//DS args[i]
Console.WriteLine(args[i]);
}
Console.ReadKey();
}
//Asp.net
public static void Main(string[] args)
{
//不支持 AOT 方案
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors();
var app = builder.Build();
app.UseStaticFiles();
//.....等等其他设置
//销毁 app 等一系列可销毁的对象。
//方法1 :
HEProxy.SetPreHotExecut(async () => { await app.DisposeAsync(); });
//方法2 :
app.AsyncToHotExecutor();
await app.RunAsync();
Console.ReadKey();
}
//Winform
[STAThread]
static void Main()
{
//Once
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
//Or 两种初始化均支持
Application.Run(new ApplicationContext(new Form1()));
}
}
注:winform 若不使用 SG 则需在 主逻辑中添加不少管理 form 生命周期的代码。
sequenceDiagram
participant User
participant HEProxy
participant HETreeMethodRewriter
participant HETreeTriviaRewriter
User->>HEProxy: Start Hot Compilation
activate HEProxy
HEProxy->>HETreeMethodRewriter: Register Method Plugins
activate HETreeMethodRewriter
HETreeMethodRewriter->>HEProxy: Plugins Registered
deactivate HETreeMethodRewriter
HEProxy->>HETreeTriviaRewriter: Register Trivia Plugins
activate HETreeTriviaRewriter
HETreeTriviaRewriter->>HEProxy: Plugins Registered
deactivate HETreeTriviaRewriter
HEProxy->>HEProxy: Rewrite Methods and Comments with Plugins
User->>HEProxy: Complete Hot Compilation
deactivate HEProxy
在热执行环境中,热执行库本身为高权限操作库,Main 首次执行会将主逻辑交给 [热执行库] 进行[域代理运行],因此后续除非更改依赖库 源码、 csproj 文件触发重建。
举例:
假设我们需要统计重建次数,正常需要在 Program 类中增加一个全局计数的变量,private static int counter.
但是如果触发热执行, 那么整个程序包括 Program 也将在一个新的域中执行。所以每次热执行你的 program 都将是一份新的。
为此我增加了 HEProxyState 作为状态机的操作。
//设置
HEProxyState .SetValue(0);
//或
HEProxyState <int>.Value = 0;
//增加计数
HEProxyState <int>.Value+=1;
HEProxyState <T>
为泛型方法,接收不同类型的值。
仅支持 .NET5.0 及以上版本.
控制台,全程只需进行注释 //Once
即可.
Asp.net Core 传递被注销的对象即可.
在组件命名空间无冲突情况下运行正常.
出现 VB 命名空间的干扰,引申出复杂运行环境下不可预知的 CS0104 问题,由本身的 Using 引用和默认 using 集覆盖二者结合解决。
在复杂环境,HE 支持在每个文件中使用 //HE: CS0104 + 命名空间 来手动剔除当前文件发生冲突的 UsingCode.
模式切换
执行模式(同/异步)
代码剔除
CS0104 问题
预处理表达式输出
Console.ReadKey()
表达式.
📃 计划清单 (Tasklist).