FODY會將相關的程式集處理成資源檔案,CS_SCRIPT強制要求參考的程式集必須是檔案
@@@codepublic override IEvaluator ReferenceAssembly(Assembly assembly)
{
if (assembly != null)//this check is needed when trying to load partial name assemblies that result in null
{
if (assembly.Location.IsEmpty())
throw new Exception(
$"Current version of CodeDom evaluator (csc.exe) doesn't support referencing assemblies " +
"which are not loaded from the file location.");
var asmFile = assembly.Location;
if (referencedAssemblies.FirstOrDefault(x => asmFile.SamePathAs(x)) == null)
referencedAssemblies.Add(asmFile);
}
return this;
}
@@#
解決辦法:
- 動態代碼涉及到的命名空間放在一個公共的程式集中,最好是介面描述,FODY生成的時候,將這個程式集排除在外
- 上述方法沒辦法做到發布為單一檔案,畢竟使用FODY就是為了只生成一個檔案,可強行在代碼中在編譯動態代碼前,釋放該檔案,(缺點:該程式集名稱固定在了代碼中)
//fody時無法加載程式集,釋放到臨時檔案使用(不在當前目錄下,防止釋放后不能洗掉,下次程式啟動時優先從檔案加載此程式集)
string protocolDll = FileHelper.GetAbsolutePath(Path.Combine("scripts", "Protocol.dll"));
AssemblyUtil.ExtractFodyDll(protocolDll, "protocol.dll");
//添加臨時目錄為程式集搜索目錄
CSScript.GlobalSettings.AddSearchDir(Path.GetDirectoryName(protocolDll));
//動態執行代碼獲取所有資料
CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
// // CSScript.EvaluatorConfig.Engine = EvaluatorEngine.Roslyn;
//該方法與FODY沖突,FODY會導致無法找到參考
script = CSScript.Evaluator.ReferenceDomainAssemblies(DomainAssemblies.AllStaticNonGAC);
script.ReferenceAssembly(Path.GetFileName(protocolDll));//添加釋放出的程式集
public static void ExtractFodyDll(string fileName, string dllName)
{
System.Reflection.Assembly Asmb = System.Reflection.Assembly.GetCallingAssembly();
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(fileName)))
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(fileName));
string strName = "costura." + dllName;
using (System.IO.Stream ManifestStream = Asmb.GetManifestResourceStream(strName))
{
if (strName.EndsWith(".compressed"))
{
using (DeflateStream source = new DeflateStream(ManifestStream, CompressionMode.Decompress))
using (FileStream output = new FileStream(fileName, FileMode.Create))
source.CopyTo(output);
}
else
{
byte[] StreamData = https://www.cnblogs.com/QinQouShui/archive/2022/11/17/new byte[ManifestStream.Length];
ManifestStream.Read(StreamData, 0, (int)ManifestStream.Length);
System.IO.File.WriteAllBytes(fileName, StreamData);
}
}
}
@@#
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/535946.html
標籤:.NET技术
