我需要获取一些关于调用我的组件的程序集的元数据。因此,使用Assembly.GetCallingAssembly()
似乎很自然。但是,除了在Windows应用商店中,我发现它可以在任何地方使用。在哪里得到支持:
但是,不支持的地方直接位于Windows应用商店应用中。我可以创建一个可移植的类库,然后从Windows应用程序内部调用它,但我不能直接将它放在Windows应用商店应用程序/类库中。
是否有针对这种或其他方式的解决方法来获取Assembly
提供的元数据类型?
答案 0 :(得分:7)
Assembly.GetCallingAssembly
- 因为它的语义在面向内联等(source)时是不可靠的,但它也不适合Windows中允许的受限反射存储应用。您可以获得类似Assembly.GetCurrentAssembly()
的内容,例如:
typeof(MainPage).GetTypeInfo().Assembly
但那根本不一样。使用受限制的反射模型,也无法在.NET中获得运行时的堆栈跟踪。
对于可移植类库,我原则上说,Assembly.GetCurrentAssembly()
一般在可移植类库中受支持,但不在WinRT中 - 如果它不在该平台中则会有意义。但实际上,它似乎存在于包括WinRT在内的所有配置文件中,除了WinRT + .NET4.5之外 - 似乎必须存在某种疏忽,这种不一致。因此,方法 存在于WinRT中(而且还没有进行重定向),但在编译时可用的元数据中不可见。
因此,您可以使用反射调用该方法:
var assembly = (Assembly) typeof(Assembly).GetTypeInfo()
.GetDeclaredMethod("GetCallingAssembly")
.Invoke(null, new object[0]);
我认为Windows应用商店应用中此方法的不可见性是“我们希望这会消失”。
(这个答案只涉及“我可以”而不是“我应该”)。
答案 1 :(得分:2)
该方法被简化,因为它在WinRT应用程序中太不可靠。 WinRT的一个强大设计目标是使不同语言运行时环境之间的互操作变得简单且无故障。哪个效果很好,您可以使用C#等语言轻松创建WinRT组件,并将其用于使用非托管语言(如C ++或Javascript)编写的应用程序。
这在桌面.NET应用程序中也是可行的,但它要复杂得多,不得不回退到[ComVisible]程序集或使用C ++ / CLI语言创建混合模式程序集。在这种情况下使用Assembly.GetCallingAssembly()也会失败,但程序员完全希望失败,因为他非常清楚做某些特别的事情。
在WinRT组件中变得更加模糊。特别是因为如果调用实际上是从另一个.NET程序集中进行的,那么它就不会失败。但是当它来自非托管代码时没有希望。
如果没有一个像样的解决办法,这种随机的失败就是彻头彻尾的痛苦。因此,该方法被削减。使用PCL是一种可行的解决方法,但微软过去曾严厉警告过,这类黑客病是非常不受推荐的。具有非零赔率,它将被商店验证程序捕获并导致拒绝。