Skip to content
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

Any #262

Merged
merged 2 commits into from
Jan 5, 2024
Merged

Any #262

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions samples/PluginSample/PluginSample/PluginSample.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand All @@ -12,7 +12,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Natasha.CSharp\Core\Natasha.Domain\Natasha.Domain.csproj" />
<ProjectReference Include="..\..\..\src\Natasha.CSharp\Component\Core\Natasha.Domain\Natasha.Domain.csproj" />
<ProjectReference Include="..\PluginBase\PluginBase.csproj" />
</ItemGroup>

Expand Down
30 changes: 16 additions & 14 deletions samples/ReferenceSample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ static void Main(string[] args)
//var a = typeof(CodecovMonitor);
//var b = typeof(A);
//NatashaManagement.Preheating(true, true);
NatashaManagement.RegistDomainCreator<NatashaDomainCreator>();
TestMini();
TestMini();
//NatashaManagement.RegistDomainCreator<NatashaDomainCreator>();
//TestMini();
//TestMini();
//var a = Math.Min(1, args.Length);
//NatashaManagement.Preheating(false, false);
NatashaManagement.Preheating<NatashaDomainCreator>(true, true);
//Console.WriteLine("=============================");
//AssemblyCSharpBuilder builder = new();
//var asm = builder
Expand Down Expand Up @@ -89,11 +89,12 @@ public static void TestMini1()
//.WithFileOutput()
.WithDebugCompile(item => item.WriteToAssembly())
.UseSimpleMode()
.AddReferenceAndUsingCode(typeof(Math).Assembly)
.AddReferenceAndUsingCode(typeof(MathF).Assembly)
.AddReferenceAndUsingCode(typeof(A))
.AddReferenceAndUsingCode(typeof(CodecovMonitor))
.AddReferenceAndUsingCode(typeof(SuppressMessageAttribute))
.ConfigLoadContext(ldc=> ldc
.AddReferenceAndUsingCode(typeof(Math).Assembly)
.AddReferenceAndUsingCode(typeof(MathF).Assembly)
.AddReferenceAndUsingCode(typeof(A))
.AddReferenceAndUsingCode(typeof(CodecovMonitor))
.AddReferenceAndUsingCode(typeof(SuppressMessageAttribute)))
;

builder.Add(@"
Expand Down Expand Up @@ -132,11 +133,12 @@ public static void TestMini()
//.WithFileOutput()
.WithDebugCompile(item => item.WriteToAssembly())
.UseSimpleMode()
.AddReferenceAndUsingCode(typeof(Math).Assembly)
.AddReferenceAndUsingCode(typeof(MathF).Assembly)
.AddReferenceAndUsingCode(typeof(A))
.AddReferenceAndUsingCode(typeof(CodecovMonitor))
.AddReferenceAndUsingCode(typeof(SuppressMessageAttribute))
.ConfigLoadContext(ldc=>ldc
.AddReferenceAndUsingCode(typeof(Math).Assembly)
.AddReferenceAndUsingCode(typeof(MathF).Assembly)
.AddReferenceAndUsingCode(typeof(A))
.AddReferenceAndUsingCode(typeof(CodecovMonitor))
.AddReferenceAndUsingCode(typeof(SuppressMessageAttribute)))
;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;</TargetFrameworks>
<Description>Natasha 的编译模板</Description>
<PackageId>DotNetCore.Natasha.CSharp.Template</PackageId>
<PackageId>DotNetCore.Natasha.CSharp.Template.Core</PackageId>
<PackageReleaseNotes>升级到最新版.</PackageReleaseNotes>
<PackageTags>Roslyn;Script;Dynamic;Natasha;NMS;Template;</PackageTags>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand Down
17 changes: 6 additions & 11 deletions src/Natasha.CSharp/Natasha.CSharp.Compiler/NatashaInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,13 @@ public static void Preheating(Func<AssemblyName?, string?, bool>? excludeReferen

_excludeReferencesFunc = excludeReferencesFunc;
#if DEBUG
//StopwatchExtension.EnableMemoryMonitor();
Stopwatch stopwatchTotal = new();
stopwatchTotal.Start();
#endif

AssemblyCSharpBuilder.HasInitialized = true;
_isCompleted = true;


//var randomDomain = DomainManagement.Random();

var task = Task.Run(() =>
{

Expand All @@ -62,24 +58,18 @@ public static void Preheating(Func<AssemblyName?, string?, bool>? excludeReferen
Natasha.CSharp.Compiler.CompilerBinderFlags.UncheckedRegion)
)
.ConfigLoadContext(load=>load.AddReferenceAndUsingCode(typeof(object)))
.WithoutInjectToDomain()
.FastAddScriptWithoutCheck("public class A{}");
tempBuilder.GetAssembly();
tempBuilder.Domain.Dispose();

});



#if DEBUG
Stopwatch stopwatch = new();
stopwatch.Start();
stopwatch.RestartAndShowCategoreInfo("[ Domain ]", "默认信息初始化", 1);
#endif

var assemblies = NatashaAsssemblyHelper.GetRuntimeAssemblies();
#if DEBUG
stopwatch.RestartAndShowCategoreInfo("[ Assembly ]", "程序集扫描与加载", 1);
#endif
Queue<ParallelLoopResult> parallelLoopResults = [];
var namespaceCacheFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Natasha.Namespace.cache");
//不需要处理 using
Expand All @@ -91,6 +81,7 @@ public static void Preheating(Func<AssemblyName?, string?, bool>? excludeReferen
NatashaLoadContext.DefaultContext.UsingRecorder.Using(namespaceText);
if (useRuntimeReference)
{
var assemblies = NatashaAsssemblyHelper.GetRuntimeAssemblies();
parallelLoopResults.Enqueue(InitReferenceFromRuntime(assemblies));
}
else
Expand All @@ -112,10 +103,12 @@ public static void Preheating(Func<AssemblyName?, string?, bool>? excludeReferen
{
if (useRuntimeUsing)
{
var assemblies = NatashaAsssemblyHelper.GetRuntimeAssemblies();
parallelLoopResults.Enqueue(InitReferenceAndUsingFromRuntime(assemblies));
}
else
{
var assemblies = NatashaAsssemblyHelper.GetRuntimeAssemblies();
parallelLoopResults.Enqueue(InitReferenceFromRuntime(assemblies));
var paths = NatashaAsssemblyHelper.GetReferenceAssmeblyFiles(excludeReferencesFunc);
if (paths != null && paths.Any())
Expand All @@ -136,6 +129,7 @@ public static void Preheating(Func<AssemblyName?, string?, bool>? excludeReferen
if (useRuntimeUsing)
{
parallelLoopResults.Enqueue(InitReferenceFromPath(paths));
var assemblies = NatashaAsssemblyHelper.GetRuntimeAssemblies();
parallelLoopResults.Enqueue(InitUsingFromRuntime(assemblies));
}
else
Expand Down Expand Up @@ -167,6 +161,7 @@ public static void Preheating(Func<AssemblyName?, string?, bool>? excludeReferen
cSharpBuilder
.UseRandomDomain()
.UseSmartMode()
.WithoutInjectToDomain()
.FastAddScriptWithoutCheck(@"public class B{}")
.GetAssembly();

Expand Down
147 changes: 46 additions & 101 deletions src/Natasha.CSharp/Natasha.CSharp.Compiler/NatashaManagement.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,50 @@
using Natasha.CSharp.Compiler.Component;
using Natasha.DynamicLoad.Base;
using System;
using System.Diagnostics;
using System.Reflection;

public static partial class NatashaManagement
{
public static void Preheating<T>(Func<AssemblyName?, string?, bool>? excludeReferencesFunc,
/// <summary>
/// 预热方法
/// </summary>
/// <typeparam name="TCreator">实现 INatashaDynamicLoadContextCreator 的类</typeparam>
/// <param name="excludeReferencesFunc"></param>
/// <param name="useRuntimeUsing">是否使用实现程序集的 using</param>
/// <param name="useRuntimeReference">是否使用实现程序集的元数据</param>
/// <param name="useFileCache">是否使用 using 缓存</param>
public static void Preheating<TCreatorT>(Func<AssemblyName?, string?, bool>? excludeReferencesFunc,
bool useRuntimeUsing = false,
bool useRuntimeReference = false,
bool useFileCache = false) where T : INatashaDynamicLoadContextCreator, new ()
bool useFileCache = false) where TCreatorT : INatashaDynamicLoadContextCreator, new ()
{
RegistDomainCreator<T>();
RegistDomainCreator<TCreatorT>();
NatashaInitializer.Preheating(excludeReferencesFunc, useRuntimeUsing, useRuntimeReference, useFileCache);
}

public static void Preheating<T>(
/// <summary>
/// 预热方法
/// </summary>
/// <typeparam name="TCreator">实现 INatashaDynamicLoadContextCreator 的类</typeparam>
/// <param name="useRuntimeUsing">是否使用实现程序集的 using</param>
/// <param name="useRuntimeReference">是否使用实现程序集的元数据</param>
/// <param name="useFileCache">是否使用 using 缓存</param>
public static void Preheating<TCreator>(
bool useRuntimeUsing = false,
bool useRuntimeReference = false,
bool useFileCache = false) where T : INatashaDynamicLoadContextCreator, new()
bool useFileCache = false) where TCreator : INatashaDynamicLoadContextCreator, new()
{
RegistDomainCreator<T>();
RegistDomainCreator<TCreator>();
NatashaInitializer.Preheating(null, useRuntimeUsing, useRuntimeReference, useFileCache);
}

/// <summary>
/// 和 NatashaInitializer.Preheating(); 一样
/// 预热方法,调用此方法之前需要调用 RegistDomainCreator<TCreatorT> 确保域的创建
/// </summary>
/// <param name="excludeReferencesFunc"></param>
/// <param name="useRuntimeUsing">是否使用实现程序集的 using</param>
/// <param name="useRuntimeReference">是否使用实现程序集的元数据</param>
/// <param name="useFileCache">是否使用 using 缓存</param>
public static void Preheating(
Func<AssemblyName?, string?, bool>? excludeReferencesFunc,
bool useRuntimeUsing = false,
Expand All @@ -34,6 +53,13 @@ public static void Preheating(
{
NatashaInitializer.Preheating(excludeReferencesFunc, useRuntimeUsing, useRuntimeReference, useFileCache);
}

/// <summary>
/// 预热方法,调用此方法之前需要调用 RegistDomainCreator<TCreatorT> 确保域的创建
/// </summary>
/// <param name="useRuntimeUsing">是否使用实现程序集的 using</param>
/// <param name="useRuntimeReference">是否使用实现程序集的元数据</param>
/// <param name="useFileCache">是否使用 using 缓存</param>
public static void Preheating(
bool useRuntimeUsing = false,
bool useRuntimeReference = false,
Expand All @@ -42,45 +68,23 @@ public static void Preheating(
NatashaInitializer.Preheating(null, useRuntimeUsing, useRuntimeReference, useFileCache);
}

public static void RegistDomainCreator<T>() where T : INatashaDynamicLoadContextCreator, new()
{
NatashaLoadContext<T>.Prepare();
}

/// <summary>
/// 增加全局 Using 引用,其他编译将默认添加该 Using
/// 例如: AddGlobalUsing("System.IO");
/// 注册域的实现
/// </summary>
/// <param name="namespaces"></param>
public static void AddGlobalUsing(params string[] @namespaces)
/// <typeparam name="TCreator">INatashaDynamicLoadContextCreator 的实现类</typeparam>
public static void RegistDomainCreator<TCreator>() where TCreator : INatashaDynamicLoadContextCreator, new()
{
NatashaLoadContext.DefaultContext.UsingRecorder.Using(@namespaces);
#if DEBUG
//StopwatchExtension.EnableMemoryMonitor();
Stopwatch stopwatch = new();
stopwatch.Start();
#endif
NatashaLoadContext<TCreator>.Prepare();
#if DEBUG
stopwatch.StopAndShowCategoreInfo("[ Regist Domain ]", "注册域实现", 1);
#endif
}

/// <summary>
/// 增加全局 Using 引用,其他编译将默认添加该 Using
/// 例如: AddGlobalUsing("System.IO");
/// </summary>
/// <param name="namespaces"></param>
public static void AddGlobalUsing(params Assembly[] @namespaces)
{
foreach (var item in @namespaces)
{
NatashaLoadContext.DefaultContext.UsingRecorder.Using(item);


}
}

/// <summary>
/// 移除全局 Using 引用
/// 例如: RemoveGlobalUsing("System.IO");
/// </summary>
/// <param name="namespaces"></param>
public static void RemoveGlobalUsing(params string[] @namespaces)
{
NatashaLoadContext.DefaultContext.UsingRecorder.Remove(@namespaces);
}

/// <summary>
/// 获取系统域
Expand All @@ -107,64 +111,5 @@ public static NatashaLoadContext CreateRandomDomain()
{
return DomainManagement.Random();
}

/// <summary>
/// 增加元数据引用,从内存中提取实现程序集并加载到共享域中.
/// </summary>
/// <param name="type"></param>
/// <param name="loadBehavior">加载行为,如果有相同类型的引用, 那么此枚举会比较新旧程序集版本</param>
/// <returns></returns>
public static bool AddGlobalReferenceAndUsing(Type type, AssemblyCompareInfomation loadBehavior = AssemblyCompareInfomation.None)
{
return AddGlobalReferenceAndUsing(type.Assembly, loadBehavior);
}
/// <summary>
/// 增加元数据引用,从内存中提取实现程序集并加载到共享域中.
/// </summary>
/// <param name="assembly"></param>
/// <param name="loadBehavior"></param>
/// <returns></returns>
public static bool AddGlobalReferenceAndUsing(Assembly assembly, AssemblyCompareInfomation loadBehavior = AssemblyCompareInfomation.None)
{
var result = MetadataHelper.GetMetadataAndNamespaceFromMemory(assembly);
if (result != null)
{
NatashaLoadContext.DefaultContext.AddReferenceAndUsing(result.Value.asmName, result.Value.metadata, result.Value.namespaces, loadBehavior);
return true;
}
return false;
}

/// <summary>
/// 增加元数据以及UsingCode, 从文件中提取元数据并加载到共享域中。
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public static bool AddGlobalReferenceAndUsing(string filePath, AssemblyCompareInfomation loadBehavior = AssemblyCompareInfomation.None)
{
var result = MetadataHelper.GetMetadataAndNamespaceFromFile(filePath);
if (result != null)
{
NatashaLoadContext.DefaultContext.AddReferenceAndUsing(result.Value.asmName, result.Value.metadata, result.Value.namespaces, loadBehavior);
return true;
}
return false;
}

/// <summary>
/// 移除元数据引用,编译需要元数据支持.
/// </summary>
/// <param name="type"></param>
/// <param name="loadBehavior">加载行为,如果有相同类型的引用, 那么此枚举会比较新旧程序集版本</param>
/// <returns></returns>
public static bool RemoveGlobalReference(Type type, AssemblyCompareInfomation loadBehavior = AssemblyCompareInfomation.None)
{
if (type.Assembly.IsDynamic || type.Assembly.GetName() == null)
{
return false;
}
NatashaLoadContext.DefaultContext.ReferenceRecorder.RemoveReference(type.Assembly.GetName());
return true;
}
}

Loading
Loading