gpt4 book ai didi

c# - 从库代码中发现程序集

转载 作者:行者123 更新时间:2023-11-30 18:01:35 24 4
gpt4 key购买 nike

我在公共(public)库中有一些代码来支持国际化。基本思想是,给定 RESX 文件位置的完全限定名称,您可以使用标记扩展查找值:

    resx:ResxProperty.Name="SampleApp.Common.Resources.MainWindow"
Title="{Resx Key=Window.Title}"
Icon="{Resx Key=Window.Icon}"

要查找 RESX 文件,有一个例程可以搜索所有程序集,如下所示,当 RESX 文件与 xaml 位于同一程序集中时,它可以正常工作。但如果不是,它就会崩溃。

考虑下面的解决方案结构,其中 SampleApp.Wpf 具有调用 XAML 并且依赖于 LocalizationLib 和 SampleApp.Common。

enter image description here

AppDomain.CurrentDomain.GetAssemblies() 在运行时没有 SampleApp.Common(尽管它在设计时有)。

如何修改此代码,使其在运行时了解 SampleApp.Common?

干杯,
贝瑞尔

图书馆代码

/// <summary>
/// Find the assembly that contains the type
/// </summary>
/// <returns>The assembly if loaded (otherwise null)</returns>
public static Assembly FindResourceAssembly(string resxName)
{
// check the entry assembly first - this will short circuit a lot of searching
//
var assembly = Assembly.GetEntryAssembly();
if (assembly != null && HasSpecifiedResx(assembly, resxName))
return assembly;

var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var searchAssembly in assemblies)
{
// skip system assemblies
var name = searchAssembly.FullName;
if (_isSystemAssembly(name)) continue;

if (HasSpecifiedResx(searchAssembly, resxName))
return searchAssembly;
}
return null;
}

更新

更多细节。

SampleApp.Wpf 的目标是 .net 4.0。下面是它在 Visual Studio 中显示的引用。

enter image description here

其中唯一的项目引用是 Infralution.Localization.Wpf 和 SampleApp.Common,它们也都针对 .Net 4.0。

根据 Metro Smurf 的输入,我尝试使用 assembly.GetReferencedAssemblies()。当我使用此方法时,VS 设计器未找到 SampleApp.Common,并且在运行时调试器中已知以下 AssemblyNames:

{System.Reflection.AssemblyName[6]}
[0]: {PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35}
[1]: {mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[2]: {System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[3]: {Infralution.Localization.Wpf, Version=2.1.2.0, Culture=neutral, PublicKeyToken=547ccae517a004b5}
[4]: {System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[5]: {PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35}

当我使用原始的 AppDomain.CurrentDomain.GetAssemblies() 时,设计者确实知道 SampleApp.Common,并且这些程序集在运行时是已知的:

?AppDomain.CurrentDomain.GetAssemblies()
{System.Reflection.RuntimeAssembly[21]}
[0]: {mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[1]: {Microsoft.VisualStudio.HostingProcess.Utilities, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a}
[2]: {System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[3]: {System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a}
[4]: {System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[5]: {Microsoft.VisualStudio.HostingProcess.Utilities.Sync, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a}
[6]: {Microsoft.VisualStudio.Debugger.Runtime, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a}
[7]: {vshost32, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a}
[8]: {System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[9]: {System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[10]: {System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[11]: {Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a}
[12]: {System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[13]: {System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[14]: {System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[15]: {WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35}
[16]: {PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35}
[17]: {PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35}
[18]: {SampleApp.Wpf, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}
[19]: {System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a}
[20]: {Infralution.Localization.Wpf, Version=2.1.2.0, Culture=neutral, PublicKeyToken=547ccae517a004b5}

在这两种情况下,SampleApp.Common 在运行时都是未知的。为了好玩,我将该程序集加载到调试器中并得到:

?Assembly.Load("SampleApp.Common")
{SampleApp.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}
[System.Reflection.RuntimeAssembly]: {SampleApp.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}
CodeBase: "file:///C:/.../SampleApp.Wpf/bin/Release/SampleApp.Common.DLL"
EntryPoint: null
EscapedCodeBase: "file:///C:.../SampleApp.Wpf/bin/Release/SampleApp.Common.DLL"
Evidence: {System.Security.Policy.Evidence}
FullName: "SampleApp.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
GlobalAssemblyCache: false
HostContext: 0
ImageRuntimeVersion: "v4.0.30319"
IsDynamic: false
IsFullyTrusted: true
Location: "C:\\...\\SampleApp.Wpf\\bin\\Release\\SampleApp.Common.dll"
ManifestModule: {SampleApp.Common.dll}
PermissionSet: {<PermissionSet class="System.Security.PermissionSet"
version="1"
Unrestricted="true"/>
}
ReflectionOnly: false
SecurityRuleSet: Level2

我还尝试了 Metro Smurf 的建议,在 SampleApp.Wpf 中引用来自 SampleApp.Common 的静态字符串。那个没有变化,尽管我想它进一步证明了 SampleApp.Common 被正确引用。

要在 SampleApp.Common 上尝试的其他事情可能包括添加 EntryPoint、SNK 或 HashAlgorithm。

修复

asm.GetReferencedAssemblies 听起来 像票证,但它只返回加载到内存中的程序集,如果未在代码中引用,则不会加载程序集(令人困惑的是,虽然说一个项目引用了另一个项目也很恰当,但这不是该方法返回的那种引用)。

事实证明,AppDomain.CurrentDomain.GetAssemblies() 的工作方式相同。

Metro Smurf 走在正确的轨道上,但显然静态引用不会加载程序集,但可以从程序集创建类型实例。所以:

Console.WriteLine(Class1.MyDummyString)  // this won't do it
Console.WriteLine(new Class1()) // finally, the assembly is loaded

尽管我不喜欢创建一个虚拟类,但在这种情况下它很容易修复;我可以保留原始库代码。

最佳答案

您可能需要考虑使用 Assembly.GetReferencedAssemblies Method .但是,如果我没记错的话,您还需要排除框架程序集。

关于c# - 从库代码中发现程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9007903/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com