西河刘卡车医 发表于 2022-11-18 01:32:09

使用Fody时,CS-SCRIPT动态代码无法找到程序集

FODY会将相关的程序集处理成资源文件,CS_SCRIPT强制要求引用的程序集必须是文件

@@@code
public                                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就是为了只生成一个文件,可强行在代码中在编译动态代码前,释放该文件。(缺点:该程序集名称固定在了代码中)

@@@code
                        //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 = new                                                                byte;
                  ManifestStream.Read(StreamData, 0, (int)ManifestStream.Length);
                  System.IO.File.WriteAllBytes(fileName, StreamData);
                        }                               
                        }                               
                                }               
@@#


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 使用Fody时,CS-SCRIPT动态代码无法找到程序集