diff --git a/src/CSScriptLib/src/CSScriptLib/CSScriptLib.csproj b/src/CSScriptLib/src/CSScriptLib/CSScriptLib.csproj
index bcadf1b2..97a2a328 100644
--- a/src/CSScriptLib/src/CSScriptLib/CSScriptLib.csproj
+++ b/src/CSScriptLib/src/CSScriptLib/CSScriptLib.csproj
@@ -1,129 +1,131 @@
-
- netstandard2.0
- CSScriptLib
- latest
- CS-Script
-
-
- false
- false
- false
- true
- true
- true
- snupkg
- true
- 4.14.7.0
- Oleg Shilo
- CS-Script engine Class Library for .NET
- (C) 2018-2026 Oleg Shilo
-
- https://github.com/oleg-shilo/cs-script
-
- https://github.com/oleg-shilo/cs-script.git
- Git
- C#, scripting, script, dynamic, .NET. .NET Core
- ---
+
+ netstandard2.0
+ CSScriptLib
+ latest
+ CS-Script
+
+
+ false
+ false
+ false
+ true
+ true
+ true
+ snupkg
+ true
+ 4.14.8.0
+ Oleg Shilo
+ CS-Script engine Class Library for .NET
+ (C) 2018-2026 Oleg Shilo
+
+ https://github.com/oleg-shilo/cs-script
+
+ https://github.com/oleg-shilo/cs-script.git
+ Git
+ C#, scripting, script, dynamic, .NET. .NET Core
+
+ ---
-## Changes
+ ## Changes
-### CLI
+ ### CLI
-- <no changes>
+ - <no changes>
-### CSScriptLib
+ ### CSScriptLib
-- #453: CSScriptLib: allow //css_precompiler directive proessing for Roslyn compiler engine.
- true
- 4.14.7.0
- 4.14.7.0
- 4.14.7.0
- MIT
- css_logo.png
- True
- sgKey.snk
-
-
-
-
-
- CSScriptLib.xml
- AnyCPU
- TRACE;class_lib
-
-
- CSScriptLib.xml
- TRACE;class_lib
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
-
-
-
-
-
-
-
-
-
- Resources.resx
- True
- True
-
-
-
-
- Resources.Designer.cs
- ResXFileCodeGenerator
- CSScripting
-
-
-
-
-
+ - #453: CSScriptLib: allow //css_precompiler directive proessing for Roslyn compiler engine.
+
+ true
+ 4.14.8.0
+ 4.14.8.0
+ 4.14.8.0
+ MIT
+ css_logo.png
+ True
+ sgKey.snk
+
+
+
+
+
+ CSScriptLib.xml
+ AnyCPU
+ TRACE;class_lib
+
+
+ CSScriptLib.xml
+ TRACE;class_lib
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+ Resources.resx
+ True
+ True
+
+
+
+
+ Resources.Designer.cs
+ ResXFileCodeGenerator
+ CSScripting
+
+
+
+
+
\ No newline at end of file
diff --git a/src/CSScriptLib/src/CSScriptLib/Evaluator.CodeDom.cs b/src/CSScriptLib/src/CSScriptLib/Evaluator.CodeDom.cs
index bbf89b0f..becc862a 100644
--- a/src/CSScriptLib/src/CSScriptLib/Evaluator.CodeDom.cs
+++ b/src/CSScriptLib/src/CSScriptLib/Evaluator.CodeDom.cs
@@ -38,6 +38,7 @@
using System.Reflection;
using System.Text;
using System.Threading;
+using Microsoft.CodeAnalysis.Scripting;
using csscript;
using CSScripting;
using CSScripting.CodeDom;
@@ -167,6 +168,66 @@ protected override void Validate(CompileInfo info)
"named parent class. You are using CodeDomEvaluator so you should not set CompileInfo.RootClass to any custom value");
}
+ ///
+ /// Resets Evaluator.
+ ///
+ /// Resetting means clearing all referenced assemblies, recreating evaluation infrastructure
+ /// (e.g. compiler setting) and reconnection to or recreation of the underlying compiling services.
+ ///
+ ///
+ /// Optionally the default current AppDomain assemblies can be referenced automatically with
+ /// .
+ ///
+ ///
+ ///
+ /// if set to true the default assemblies of the current AppDomain will be referenced
+ /// (see method).
+ ///
+ /// The freshly initialized instance of the .
+ public override IEvaluator Reset(bool referenceDomainAssemblies = true)
+ {
+ referencedAssemblies.Clear();
+ referencedAssembliesAliases.Clear();
+
+ if (referenceDomainAssemblies)
+ ReferenceDomainAssemblies();
+
+ return this;
+ }
+
+ ///
+ /// Clones itself as .
+ ///
+ /// This method returns a freshly initialized copy of the
+ /// . The cloning 'depth' can be
+ /// controlled by the .
+ ///
+ ///
+ /// This method is a convenient technique when multiple
+ /// instances are required (e.g.
+ /// for concurrent script evaluation).
+ ///
+ ///
+ /// if set to true all referenced
+ /// assemblies from the parent
+ /// will be referenced in the cloned copy.
+ /// The freshly initialized instance of the
+ /// .
+ public override IEvaluator Clone(bool copyRefAssemblies = true)
+ {
+ var clone = new CodeDomEvaluator();
+ if (copyRefAssemblies)
+ {
+ clone.Reset(false);
+ foreach (var a in this.GetReferencedAssemblies())
+ clone.ReferenceAssembly(a);
+ clone.referencedAssembliesAliases.AddItems(this.referencedAssembliesAliases);
+ }
+
+ return clone;
+ }
+
///
/// Compiles the specified script text.
///
@@ -468,7 +529,14 @@ public string CompileAssemblyFromCode(string scriptText, CompileInfo info, out P
gac_asms.AddRange(Directory.GetFiles(gac, "Microsoft.*.dll").Where(x => !x.Contains("Native")));
foreach (string file in gac_asms.Concat(ref_assemblies).Distinct())
- refs_args.Add($"/r:\"{file}\"");
+ {
+ var aliasesList = "";
+
+ var aliases = AliasesOf(file);
+ if (aliases.Any())
+ aliasesList = aliases.JoinBy(",") + "=";
+ refs_args.Add($"/r:{aliasesList}\"{file}\"");
+ }
}
else
{
@@ -626,6 +694,9 @@ public string CompileAssemblyFromCode(string scriptText, CompileInfo info, out P
}
List referencedAssemblies = new List();
+ Dictionary referencedAssembliesAliases = new();
+
+ string[] AliasesOf(string assembly) => referencedAssembliesAliases.TryGetValue(assembly, out var aliases) ? aliases : [];
///
/// References the given assembly.
@@ -635,6 +706,7 @@ public string CompileAssemblyFromCode(string scriptText, CompileInfo info, out P
///
///
/// The assembly instance.
+ /// The optional aliases for the assembly.
///
/// The instance of the to allow fluent interface.
///
@@ -642,7 +714,7 @@ public string CompileAssemblyFromCode(string scriptText, CompileInfo info, out P
/// Current version of {EngineName} doesn't support referencing assemblies " + "which are
/// not loaded from the file location.
///
- public override IEvaluator ReferenceAssembly(Assembly assembly)
+ public override IEvaluator ReferenceAssembly(Assembly assembly, string[] aliases = null)
{
if (assembly != null)//this check is needed when trying to load partial name assemblies that result in null
{
@@ -655,6 +727,9 @@ public override IEvaluator ReferenceAssembly(Assembly assembly)
if (referencedAssemblies.FirstOrDefault(x => asmFile.SamePathAs(x)) == null)
referencedAssemblies.Add(asmFile);
+
+ if (aliases != null)
+ referencedAssembliesAliases[asmFile] = aliases;
}
return this;
}
diff --git a/src/CSScriptLib/src/CSScriptLib/Evaluator.Roslyn.cs b/src/CSScriptLib/src/CSScriptLib/Evaluator.Roslyn.cs
index 8ec882ce..8e35df2f 100644
--- a/src/CSScriptLib/src/CSScriptLib/Evaluator.Roslyn.cs
+++ b/src/CSScriptLib/src/CSScriptLib/Evaluator.Roslyn.cs
@@ -384,9 +384,19 @@ SyntaxTree createTree(string code, string path) =>
foreach (var asm in allRefs)
{
- var metadata = ToMetadata(asm);
+ AssemblyMetadata metadata = ToMetadata(asm);
+
if (metadata != null)
- references.Add(metadata.GetReference());
+ {
+ var mdRef = metadata.GetReference();
+
+ var aliases = AliasesOf(asm);
+
+ if (aliases.Any() && mdRef is PortableExecutableReference peRef)
+ mdRef = peRef.WithProperties(peRef.Properties.WithAliases(aliases));
+
+ references.Add(mdRef);
+ }
}
// switch (effectiveCodeKind)
@@ -591,6 +601,7 @@ SyntaxTree createTree(string code, string path) =>
///
///
/// The assembly instance.
+ /// The optional aliases for the assembly.
///
/// The instance of the to allow fluent interface.
///
@@ -598,7 +609,7 @@ SyntaxTree createTree(string code, string path) =>
/// Current version of {EngineName} doesn't support referencing assemblies " + "which are
/// not loaded from the file location.
///
- public override IEvaluator ReferenceAssembly(Assembly assembly)
+ public override IEvaluator ReferenceAssembly(Assembly assembly, string[] aliases = null)
{
//Microsoft.Net.Compilers.1.2.0 - beta
if (assembly.Location.IsEmpty() && !Runtime.IsSingleFileApplication)
@@ -607,7 +618,11 @@ public override IEvaluator ReferenceAssembly(Assembly assembly)
"which are not loaded from the file location.");
if (!refAssemblies.Contains(assembly))
+ {
refAssemblies.Add(assembly);
+ if (aliases != null)
+ refAssembliesAliases[assembly] = aliases;
+ }
return this;
}
@@ -711,6 +726,9 @@ public T Eval(string scriptText, CompileInfo info)
}
List refAssemblies = new List();
+ Dictionary refAssembliesAliases = new Dictionary();
+
+ string[] AliasesOf(Assembly assembly) => refAssembliesAliases.TryGetValue(assembly, out var aliases) ? aliases : [];
IEvaluator PrepareRefAssemblies()
{
@@ -731,11 +749,18 @@ IEvaluator PrepareRefAssemblies()
{
if (!CompilerSettings.MetadataReferences.OfType().Any(r => r.FilePath.SamePathAs(assembly.Location)))
{
- // Future assembly aliases support:
- // MetadataReference.CreateFromFile("asm.dll", new
- // MetadataReferenceProperties().WithAliases(new[] { "lib_a",
- // "external_lib_a" } })
- CompilerSettings = CompilerSettings.AddReferences(assembly);
+ var aliases = AliasesOf(assembly);
+
+ if (aliases.Any())
+ {
+ var mdRef = MetadataReference.CreateFromFile(
+ assembly.Location(),
+ new MetadataReferenceProperties().WithAliases(aliases));
+
+ CompilerSettings = CompilerSettings.AddReferences(mdRef);
+ }
+ else
+ CompilerSettings = CompilerSettings.AddReferences(assembly);
}
}
}
@@ -769,6 +794,7 @@ IEvaluator PrepareRefAssemblies()
public override IEvaluator Reset(bool referenceDomainAssemblies = true)
{
refAssemblies.Clear();
+ refAssembliesAliases.Clear();
CompilerSettings = ScriptOptions.Default;
if (referenceDomainAssemblies)
@@ -776,6 +802,38 @@ public override IEvaluator Reset(bool referenceDomainAssemblies = true)
return this;
}
+
+ ///
+ /// Clones itself as .
+ ///
+ /// This method returns a freshly initialized copy of the
+ /// . The cloning 'depth' can be
+ /// controlled by the .
+ ///
+ ///
+ /// This method is a convenient technique when multiple
+ /// instances are required (e.g.
+ /// for concurrent script evaluation).
+ ///
+ ///
+ /// if set to true all referenced
+ /// assemblies from the parent
+ /// will be referenced in the cloned copy.
+ /// The freshly initialized instance of the
+ /// .
+ public override IEvaluator Clone(bool copyRefAssemblies = true)
+ {
+ var clone = new RoslynEvaluator();
+ if (copyRefAssemblies)
+ {
+ clone.Reset(false);
+ foreach (var a in this.GetReferencedAssemblies())
+ clone.ReferenceAssembly(a);
+
+ clone.refAssembliesAliases.AddItems(this.refAssembliesAliases);
+ }
+ return clone;
+ }
}
static class localExtensions
diff --git a/src/CSScriptLib/src/CSScriptLib/EvaluatorBase.cs b/src/CSScriptLib/src/CSScriptLib/EvaluatorBase.cs
index 2e614acc..143852e7 100644
--- a/src/CSScriptLib/src/CSScriptLib/EvaluatorBase.cs
+++ b/src/CSScriptLib/src/CSScriptLib/EvaluatorBase.cs
@@ -62,33 +62,14 @@ namespace CSScriptLib
public class EvaluatorBase : IEvaluator where T : IEvaluator, new()
{
///
- /// Clones itself as .
- ///
- /// This method returns a freshly initialized copy of the
- /// . The cloning 'depth' can be
- /// controlled by the .
- ///
- ///
- /// This method is a convenient technique when multiple
- /// instances are required (e.g.
- /// for concurrent script evaluation).
- ///
+ /// Clones the current instance of the evaluator.
///
- /// if set to true all referenced
- /// assemblies from the parent
- /// will be referenced in the cloned copy.
- /// The freshly initialized instance of the
- /// .
- public IEvaluator Clone(bool copyRefAssemblies = true)
+ ///
+ ///
+ ///
+ public virtual IEvaluator Clone(bool copyRefAssemblies = true)
{
- var clone = new T();
- if (copyRefAssemblies)
- {
- clone.Reset(false);
- foreach (var a in this.GetReferencedAssemblies())
- clone.ReferenceAssembly(a);
- }
- return clone;
+ throw new NotImplementedException();
}
static Assembly mscorelib = 333.GetType().Assembly;
@@ -1280,9 +1261,10 @@ private bool ApplyPrecompilation(string script, PrecompilationContext retval, Ha
///
///
/// The path to the assembly file.
+ /// The optional aliases for the assembly.
/// The instance of the to
/// allow fluent interface.
- public IEvaluator ReferenceAssembly(string assembly)
+ public IEvaluator ReferenceAssembly(string assembly, string[] aliases = null)
{
var globalProbingDirs = CSScript.GlobalSettings.SearchDirs.ToList();
@@ -1291,7 +1273,7 @@ public IEvaluator ReferenceAssembly(string assembly)
string asmFile = AssemblyResolver.FindAssembly(assembly, dirs).FirstOrDefault()
?? throw new Exception("Cannot find referenced assembly '" + assembly + "'");
- ReferenceAssembly(Assembly.LoadFile(asmFile));
+ ReferenceAssembly(Assembly.LoadFile(asmFile), aliases);
return this;
}
@@ -1309,9 +1291,10 @@ public IEvaluator ReferenceAssembly(string assembly)
///
///
/// The assembly instance.
+ /// The optional aliases for the assembly.
/// The instance of the to
/// allow fluent interface.
- public virtual IEvaluator ReferenceAssembly(Assembly assembly)
+ public virtual IEvaluator ReferenceAssembly(Assembly assembly, string[] aliases = null)
=> throw new NotImplementedException();
///
diff --git a/src/CSScriptLib/src/CSScriptLib/IEvaluator.cs b/src/CSScriptLib/src/CSScriptLib/IEvaluator.cs
index 8fb72b59..c59844d3 100644
--- a/src/CSScriptLib/src/CSScriptLib/IEvaluator.cs
+++ b/src/CSScriptLib/src/CSScriptLib/IEvaluator.cs
@@ -875,10 +875,11 @@ public interface IEvaluator
///
///
/// The path to the assembly file.
+ /// The optional aliases for the assembly.
///
/// The instance of the to allow fluent interface.
///
- IEvaluator ReferenceAssembly(string assembly);
+ IEvaluator ReferenceAssembly(string assembly, string[] aliases = null);
///
/// References the given assembly.
@@ -888,10 +889,11 @@ public interface IEvaluator
///
///
/// The assembly instance.
+ /// The optional aliases for the assembly.
///
/// The instance of the to allow fluent interface.
///
- IEvaluator ReferenceAssembly(Assembly assembly);
+ IEvaluator ReferenceAssembly(Assembly assembly, string[] aliases = null);
///
/// References the name of the assembly by its partial name.
diff --git a/src/Tests.CSScriptLib/Evaluator.Api.Test.cs b/src/Tests.CSScriptLib/Evaluator.Api.Test.cs
index c9418121..6bdca1bf 100644
--- a/src/Tests.CSScriptLib/Evaluator.Api.Test.cs
+++ b/src/Tests.CSScriptLib/Evaluator.Api.Test.cs
@@ -43,7 +43,7 @@ public int Sum(int a, int b)
return a+b;
}
}",
- "MyScript.asm",
+ new CompileInfo { AssemblyFile = "MyScript.asm" },
out Project project);
Assert.True(File.Exists(asmFile));
@@ -101,6 +101,18 @@ string testTempFile(string fileName, [CallerMemberName] string caller = null)
return Path.Combine(rootDir, fileName);
}
+ public string testTempDll(string code, string fileName, [CallerMemberName] string caller = null)
+ {
+ var rootDir = root.PathJoin(this.GetType().Name, caller).GetFullPath().EnsureDir();
+ var filePath = Path.Combine(rootDir, fileName);
+ // try to avoid unnecessary compilations as xUnint keeps locking the loaded assemblies
+ if (!fileName.FileExists())
+ CSScript.CodeDomEvaluator
+ .CompileAssemblyFromCode(code, filePath);
+
+ return filePath;
+ }
+
public string GetTempScript(string content, [CallerMemberName] string caller = null)
{
var script = testTempFile("script.cs", $"{this.GetType().Name}.{caller}");
@@ -255,6 +267,126 @@ public class Script
eval2.LoadCode($"//css_ref {calcAsm}" + Environment.NewLine + code);
}
+ [Fact]
+ public void CompileCodeWithRefAliases()
+ {
+ var utilAsm = testTempDll(
+ @"using System;
+ using System.Reflection;
+ public class Util
+ {
+ public string GetGreeting(string name)
+ {
+ return $""Hello, {name}!"";
+ }
+ }",
+ "util.alias.dll");
+
+ Assembly resolve(object sender, ResolveEventArgs args)
+ => Assembly.LoadFile(utilAsm);
+
+ AppDomain.CurrentDomain.AssemblyResolve += resolve;
+
+ try
+ {
+ // prepare
+
+ var code = @"extern alias util_v1;
+ using Util1 = util_v1::Util;
+ using System;
+ public class Script
+ {
+ public string GetGreeting(string name) => new Util1().GetGreeting(name);
+ }";
+
+ var eval = this.new_evaluator;
+
+ // test
+
+ dynamic script = new_evaluator.ReferenceAssembly(utilAsm, ["util_v1"]).LoadCode(code);
+ var result = script.GetGreeting("John");
+
+ // assert
+
+ Assert.Equal("Hello, John!", result);
+ }
+ finally
+ {
+ AppDomain.CurrentDomain.AssemblyResolve -= resolve;
+ }
+ }
+
+ [Fact]
+ public void CompileCodeWithRefMultipleVersions()
+ {
+ var currentUtilFile = "";
+
+ Assembly resolve(object sender, ResolveEventArgs args)
+ => Assembly.LoadFile(currentUtilFile);
+
+ AppDomain.CurrentDomain.AssemblyResolve += resolve;
+
+ try
+ {
+ // prepare
+ var utilCode = @"using System;
+ using System.Reflection;
+ [assembly: AssemblyVersion(""1.0.$asmVersion$.0"")]
+ public class Util
+ {
+ public string GetGreeting(string name)
+ {
+ var version = this.GetType().Assembly.GetName().Version.ToString();
+ return $""Hello, {name} (v{version})!"";
+ }
+ }";
+
+ var utilAsm1 = testTempFile($"util.v0.dll");
+ var utilAsm2 = testTempFile($"util.v1.dll");
+
+ // try to avoid unnecessary compilations as xUnint keeps locking the loaded assemblies
+ if (!utilAsm1.FileExists())
+ CSScript.CodeDomEvaluator
+ .CompileAssemblyFromCode(utilCode.Replace("$asmVersion$", "0"),
+ utilAsm1);
+
+ if (!utilAsm2.FileExists())
+ CSScript.CodeDomEvaluator
+ .CompileAssemblyFromCode(utilCode.Replace("$asmVersion$", "1"),
+ utilAsm2);
+
+ var code = @"using System;
+ public class Script
+ {
+ public string GetGreeting(string name) => new Util().GetGreeting(name);
+ }";
+
+ var eval = this.new_evaluator;
+ eval.IsCachingEnabled = false;
+
+ // test
+
+ eval.Reset(false);
+ currentUtilFile = utilAsm1;
+ dynamic script1 = eval.ReferenceAssembly(currentUtilFile).LoadCode(code);
+ var result1 = script1.GetGreeting("John");
+
+ eval.Reset(false);
+ currentUtilFile = utilAsm2;
+ dynamic script2 = eval.ReferenceAssembly(currentUtilFile).LoadCode(code);
+ var result2 = script2.GetGreeting("John");
+
+ // assert
+
+ Assert.Equal("Hello, John (v1.0.0.0)!", result1);
+ Assert.Equal("Hello, John (v1.0.1.0)!", result2);
+ }
+ finally
+ {
+ AppDomain.CurrentDomain.AssemblyResolve -= resolve;
+ }
+ }
+
[Fact]
public void LoadCode_can_import_scripts()
{
diff --git a/src/Tests.CSScriptLib/Evaluator.Roslyn.Tests.cs b/src/Tests.CSScriptLib/Evaluator.Roslyn.Tests.cs
index 5c8c57e3..709a60bd 100644
--- a/src/Tests.CSScriptLib/Evaluator.Roslyn.Tests.cs
+++ b/src/Tests.CSScriptLib/Evaluator.Roslyn.Tests.cs
@@ -426,37 +426,73 @@ public class Script
CSScript.RoslynEvaluator.CompileAssemblyFromFile(scriptFile, calcAsm);
}
-#if DEBUG
-
// [Fact]
-#endif
+ public void Can_use_sassembly_aliases() // manual test
+ {
+ var utilAsmFile = @"D:\dev\cs-script\support\#464\util\util\bin\Debug\v1.0.0\util.dll";
+
+ AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs args) =>
+ {
+ if (args.Name.Contains("util"))
+ {
+ //return assembly;// NotSupportedException: Resolving to a collectible assembly is not supported.
+ return Assembly.LoadFrom(utilAsmFile); // will lock the assembly to the current AppDomain so it cannot be unloaded
+ }
+ return null;
+ };
+
+ // ================================
+ var scriptCode = @"extern alias util_v1;
+ using Util1 = util_v1::Util;
+ using System;
+ public class Script
+ {
+ public string GetGreeting(string name) => new Util1().GetGreeting(name);
+ }";
- public void issue_464() // manual test
+ dynamic script = CSScript.RoslynEvaluator
+ .ReferenceAssembly(utilAsmFile, ["util_v1"])
+ .LoadCode(scriptCode);
+
+ var msg = script.GetGreeting("Bender");
+
+ Assert.Equal("Hello, Bender (v1.0.0.0)!", msg);
+ }
+
+ [Fact]
+ public void issue_464_sidebyside() // manual test
{
var utilAsmFile1 = @"D:\dev\cs-script\support\#464\util\util\bin\Debug\v1.0.0\util.dll";
var utilAsmFile2 = @"D:\dev\cs-script\support\#464\util\util\bin\Debug\v1.0.1\util.dll";
var utilAsmFile = utilAsmFile1;
+ var assembly = Assembly.LoadFrom(utilAsmFile);
+
AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs args) =>
{
if (args.Name.Contains("util"))
{
- return Assembly.LoadFrom(utilAsmFile);
+ // return assembly;// NotSupportedException: Resolving to a collectible assembly is not supported.
+ // return Assembly.LoadFrom(utilAsmFile); // FileLoadException: 'Could not load file or assembly ''. The located assembly's manifest definition does not match the assembly reference. (0x80131040)'
+ return Assembly.LoadFile(utilAsmFile); // will lock the assembly to the current AppDomain so it cannot be unloaded
}
return null;
};
- var evaluator = CSScript.Evaluator;
-
+ var evaluator = CSScript.RoslynEvaluator;
// ================================
- var scriptCode = @"using System;
+ var scriptCode = @"extern alias util_v1;
+ using Util1 = util_v1::Util;
+ using System;
public class Script
{
- public string GetGreeting(string name) => new Util().GetGreeting(name);
+ public string GetGreeting(string name) => new Util1().GetGreeting(name);
}";
- dynamic script = evaluator.ReferenceAssembly(utilAsmFile)
+ evaluator.Reset(false);
+
+ dynamic script = evaluator.ReferenceAssembly(utilAsmFile, ["util_v1"])
.LoadCode(scriptCode);
var msg = script.GetGreeting("Bender");
@@ -467,10 +503,11 @@ public class Script
utilAsmFile = utilAsmFile2;
evaluator.Reset(false);
- script = evaluator.ReferenceAssembly(utilAsmFile)
- .LoadCode(scriptCode);
+ script = evaluator.ReferenceAssembly(utilAsmFile, ["util_v2"])
+ .LoadCode(scriptCode.Replace("util_v1", "util_v2"));
msg = script.GetGreeting("Bender");
+ Assert.Equal("Hello, Bender (v1.0.1.0)!", msg);
}
[Fact]