Skip to content

Commit

Permalink
Merge pull request #262 from dotnetcore/any
Browse files Browse the repository at this point in the history
Any
  • Loading branch information
NMSAzulX authored Jan 5, 2024
2 parents 7356059 + 9395751 commit ca77236
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 137 deletions.
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

0 comments on commit ca77236

Please sign in to comment.