-
Notifications
You must be signed in to change notification settings - Fork 224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
支持 .NET5.0 及以上版本低侵入完成 HotExecutor #311
Conversation
WalkthroughThe recent changes focus on updating and refactoring the Natasha.CSharp project, specifically enhancing initialization processes, removing unused namespaces, improving disposal handling for asynchronous objects, and modifying method signatures to include additional parameters for more robust script handling. These updates streamline the hot executor's functionality, ensure efficient memory management, and enhance the flexibility of dynamic script generation. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Application
participant ProjectDynamicProxy
participant NatashaManagement
User->>Application: Initialize HotExecutor
Application->>ProjectDynamicProxy: Call SetCompileInitAction
ProjectDynamicProxy->>Application: Return Control
Application->>NatashaManagement: Perform Setup Actions
NatashaManagement-->>Application: Complete Setup
Application->>User: Ready for Hot Execution
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
@coderabbitai review |
Actions performedReview triggered.
|
未检测到合适的 ISSUE 推荐给您。感谢您的反馈!
|
UT Test - Ubuntu1 tests 1 ✅ 0s ⏱️ Results for commit e0fe262. |
UT Test - Windows1 tests 1 ✅ 0s ⏱️ Results for commit e0fe262. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (7)
- src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor.SG/HotExecutorGenerator.cs (1 hunks)
- src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor/HECompiler.cs (2 hunks)
- src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor/IAsyncDisposableExtension.cs (1 hunks)
- src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor/ProjectDynamicProxy.cs (7 hunks)
- src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/StringExtension.cs (3 hunks)
- src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/SystemDelegateExtension.cs (1 hunks)
- src/Natasha.CSharp/Natasha.CSharp.Compiler/Component/Metadata/NatashaLoadContext.cs (2 hunks)
Files skipped from review due to trivial changes (1)
- src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor/HECompiler.cs
Additional comments not posted (8)
src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor/IAsyncDisposableExtension.cs (2)
3-6
: This implementation centralizes the disposal logic, which enhances maintainability and error handling.
7-10
: Consistent and efficient handling of multiple disposables. Good use of existing infrastructure to manage disposal.src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor.SG/HotExecutorGenerator.cs (1)
26-41
: The use of[ModuleInitializer]
ensures that initialization logic runs at the start, which is critical for the HotExecutor setup. Consider adding error handling for the initialization steps to enhance robustness.src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.MethodCreator/StringExtension.cs (1)
15-19
: Consistent adaptation to the new signature across different configurations. Good job maintaining uniformity in method functionalities.src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor/ProjectDynamicProxy.cs (4)
33-38
: IntroducedCompileInitAction
and its setter method to allow dynamic initialization actions. This is a flexible approach to initialization.
45-45
: Initialization ofCompileInitAction
within the static constructor ensures it's set before any instances are created, aligning with best practices for static resource management.
154-166
: RefactoredConfigPreHotExecut
to set a callback and added methods to manage async disposables. Ensure that disposal logic is robust and consider edge cases where disposables might not be correctly cleared if exceptions occur.Verification successful
The search results indicate that the file
ProjectDynamicProxy.cs
includesDisposeAsync
calls and multiplecatch
blocks. To ensure the disposal logic is robust, I will review the relevant parts of this file to verify that disposables are correctly handled, even in the presence of exceptions.
The disposal logic in
ProjectDynamicProxy.cs
appears to be robust. The code attempts to dispose of all items in_asyncDisposables
and clears the collection afterward. Exceptions during disposal are caught and logged, which helps in identifying any issues without causing resource leaks.
_asyncDisposables
are disposed of in a loop.- Exceptions during disposal are caught and logged.
- The
_asyncDisposables
collection is cleared after disposal attempts.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the robustness of async disposal logic. # Test: Search for exception handling around async disposal to ensure disposables are always cleared. rg --type csharp $'await.*DisposeAsync|catch'Length of output: 5204
Script:
#!/bin/bash # Description: Display relevant code sections from ProjectDynamicProxy.cs to verify disposal logic and exception handling. # Extract lines around DisposeAsync and catch blocks in ProjectDynamicProxy.cs rg --context 5 'DisposeAsync|catch' src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor/ProjectDynamicProxy.csLength of output: 1545
328-346
: Enhanced theHotExecute
method to support async disposal of resources. This is crucial for managing resources in a hot execution environment. Review and test thoroughly to ensure all resources are properly disposed.Verification successful
The
HotExecute
method properly handles the async disposal of resources by awaitingDisposeAsync
for each disposable object and then clearing the_asyncDisposables
list. This ensures that all resources are properly managed in the hot execution environment.
await disposableObject.DisposeAsync();
ensures that each async disposable is properly awaited._asyncDisposables.Clear();
ensures that the list of disposables is cleared after disposal.This implementation appears correct and thorough.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Ensure all async disposables are properly awaited and cleared. # Test: Search for proper use of `await` and clearing of disposables in the hot execution context. rg --type csharp $'await.*DisposeAsync|_asyncDisposables.Clear'Length of output: 368
Script:
#!/bin/bash # Description: Verify the context of async disposal lines within the `HotExecute` method. # Search for the `HotExecute` method definition and its content. ast-grep --lang csharp --pattern $'class ProjectDynamicProxy { $$$ private static async Task HotExecute() { $$$ } $$$ }'Length of output: 478
Script:
#!/bin/bash # Description: Verify the context of async disposal lines within the `HotExecute` method. # Search for the `HotExecute` method definition and its content within the `ProjectDynamicProxy` class. ast-grep --lang csharp --pattern $'class ProjectDynamicProxy { $$$ private static async Task HotExecute() { $$$ } }'Length of output: 127
Script:
#!/bin/bash # Description: Verify the context of async disposal lines within the `HotExecute` method. # Search for the `HotExecute` method definition within the codebase. ast-grep --lang csharp --pattern $'private static async Task HotExecute() { $$$ }'Length of output: 85
Script:
#!/bin/bash # Description: Verify the context of async disposal lines within the `HotExecute` method. # Search for all method definitions and their content within the `ProjectDynamicProxy` class. ast-grep --lang csharp --pattern $'class ProjectDynamicProxy { $$$ $_() { $$$ } }'Length of output: 93
Script:
#!/bin/bash # Description: Verify the context of async disposal lines within the `HotExecute` method. # Search for the `HotExecute` method name directly within the codebase. rg --type csharp 'HotExecute'Length of output: 323
Script:
#!/bin/bash # Description: Extract the full content of the `HotExecute` method for verification. # Extract the `HotExecute` method content from the `ProjectDynamicProxy.cs` file. sed -n '/private static async Task HotExecute()/,/^}/p' src/Natasha.CSharp/Extension/HotExecutor/Natasha.CSharp.Extension.HotExecutor/ProjectDynamicProxy.csLength of output: 2153
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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Effectively merges additional using statements. Consider adding unit tests to ensure the merging logic functions correctly under various scenarios.
Would you like me to help in writing these unit tests or should I open a GitHub issue to track this task?
public static (string script, string[] usings, AssemblyCSharpBuilder builder) WithAssemblyBuilder(this string script, Func<AssemblyCSharpBuilder, AssemblyCSharpBuilder> config) | ||
{ | ||
AssemblyCSharpBuilder builder = new(); | ||
config?.Invoke(builder); | ||
return (script, builder); | ||
return (script, [], builder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The addition of the usings
parameter helps in configuring using statements dynamically. Consider adding documentation to explain the new parameter and its impact on method functionality.
+ // usings: An array of namespaces to be included in the dynamically generated script.
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public static (string script, string[] usings, AssemblyCSharpBuilder builder) WithAssemblyBuilder(this string script, Func<AssemblyCSharpBuilder, AssemblyCSharpBuilder> config) | |
{ | |
AssemblyCSharpBuilder builder = new(); | |
config?.Invoke(builder); | |
return (script, builder); | |
return (script, [], builder); | |
public static (string script, string[] usings, AssemblyCSharpBuilder builder) WithAssemblyBuilder(this string script, Func<AssemblyCSharpBuilder, AssemblyCSharpBuilder> config) | |
{ | |
// usings: An array of namespaces to be included in the dynamically generated script. | |
AssemblyCSharpBuilder builder = new(); | |
config?.Invoke(builder); | |
return (script, [], builder); |
if (!_isInitialized) | ||
{ | ||
lock (_initLock) | ||
{ | ||
if (!_isInitialized) | ||
{ | ||
_isInitialized = true; | ||
Creator = new TCreator(); | ||
DefaultContext = new NatashaLoadContext(); | ||
DomainManagement.Add(DefaultName, DefaultContext); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proper implementation of the double-checked locking pattern ensures thread safety during initialization. Consider adding comments to explain the locking mechanism for future maintainability.
+ // Ensure single initialization with double-checked locking.
Committable suggestion was skipped due to low confidence.
public static Action<T1, T2, T3, T4, T5>? ToAction<T1, T2, T3, T4, T5>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Action<T1, T2, T3, T4, T5>>(); | ||
} | ||
public static Action<T1, T2, T3, T4, T5, T6>? ToAction<T1, T2, T3, T4, T5, T6>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Action<T1, T2, T3, T4, T5, T6>? ToAction<T1, T2, T3, T4, T5, T6>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Action<T1, T2, T3, T4, T5, T6>>(); | ||
} | ||
public static Action<T1, T2, T3, T4, T5, T6, T7>? ToAction<T1, T2, T3, T4, T5, T6, T7>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Action<T1, T2, T3, T4, T5, T6, T7>? ToAction<T1, T2, T3, T4, T5, T6, T7>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Action<T1, T2, T3, T4, T5, T6, T7>>(); | ||
} | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Action<T1, T2, T3, T4, T5, T6, T7, T8>>(); | ||
} | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8, T9>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8, T9>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Action<T1, T2, T3, T4, T5, T6, T7, T8, T9>>(); | ||
} | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>>(); | ||
} | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>>(); | ||
} | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>? ToAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>>(); | ||
} | ||
#endregion | ||
|
||
|
||
#region Func Delegate | ||
public static Func<T1>? ToFunc<T1>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1>? ToFunc<T1>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1>>(); | ||
} | ||
public static Func<T1, T2>? ToFunc<T1, T2>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2>? ToFunc<T1, T2>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2>>(); | ||
} | ||
public static Func<T1, T2, T3>? ToFunc<T1, T2, T3>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3>? ToFunc<T1, T2, T3>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2, T3>>(); | ||
} | ||
public static Func<T1, T2, T3, T4>? ToFunc<T1, T2, T3, T4>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3, T4>? ToFunc<T1, T2, T3, T4>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2, T3, T4>>(); | ||
} | ||
public static Func<T1, T2, T3, T4, T5>? ToFunc<T1, T2, T3, T4, T5>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3, T4, T5>? ToFunc<T1, T2, T3, T4, T5>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2, T3, T4, T5>>(); | ||
} | ||
public static Func<T1, T2, T3, T4, T5, T6>? ToFunc<T1, T2, T3, T4, T5, T6>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3, T4, T5, T6>? ToFunc<T1, T2, T3, T4, T5, T6>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2, T3, T4, T5, T6>>(); | ||
} | ||
public static Func<T1, T2, T3, T4, T5, T6, T7>? ToFunc<T1, T2, T3, T4, T5, T6, T7>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3, T4, T5, T6, T7>? ToFunc<T1, T2, T3, T4, T5, T6, T7>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2, T3, T4, T5, T6, T7>>(); | ||
} | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2, T3, T4, T5, T6, T7, T8>>(); | ||
} | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8, T9>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8, T9>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9>>(); | ||
} | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>>(); | ||
} | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) | ||
{ | ||
return buildInfo.ToDelegate<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>>(); | ||
} | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(in this (string script, AssemblyCSharpBuilder builder) buildInfo) | ||
public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>? ToFunc<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(in this (string script, string[] usings, AssemblyCSharpBuilder builder) buildInfo) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip
Codebase Verification
The instance of ToFunc<int, int, int>()
in samples/ExtensionSample/Program.cs
does not include the usings
parameter. Ensure this and any other similar instances are updated accordingly.
samples/ExtensionSample/Program.cs
: Line containing.ToFunc<int, int, int>()!;
Analysis chain
All delegate creation methods now accept a string[] usings
parameter, enhancing flexibility in specifying namespaces. Ensure all calls to these methods are updated accordingly.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify all calls to delegate creation methods in `SystemDelegateExtension` are updated to include the `usings` parameter.
# Test: Search for the method usages without the new `usings` parameter. Expect: No occurrences.
rg --type csharp $'ToAction<|ToFunc<'
Length of output: 6548
Script:
#!/bin/bash
# Description: Check if the instance of `ToFunc` in `samples/ExtensionSample/Program.cs` includes the `usings` parameter.
# Extract the line containing the instance of `ToFunc`
rg 'ToFunc<int, int, int>' samples/ExtensionSample/Program.cs
Length of output: 106
Summary by CodeRabbit
Refactor
InterceptMain
usingModuleInitializer
for improved setup actions.string[] usings
parameters for betterusing
statement handling inStringExtension
andSystemDelegateExtension
.New Features
IAsyncDisposableExtension
class to handle asynchronous disposal within a hot executor context.ProjectDynamicProxy
.HECompiler
andProjectDynamicProxy
.Bug Fixes
NatashaLoadContext
using a double-checked locking mechanism.