给定一个 System.Reflection.Assembly
实例。
当我想从当前程序集的清单资源流中加载资源时,我经常遇到这种两难选择。
事实上,如果你使用Visual Studio将文件嵌入程序集作为资源,其清单资源名称将派生自在Visual Studio项目中定义的程序集的默认命名空间。
我想到的最好的解决方案(避免在某个地方将默认命名空间硬编码为字符串)是始终确保你的资源加载代码是始终发生在与默认命名空间相同的类内部,然后可以使用以下近乎通用的方法。
此示例正在加载嵌入式模式。
XmlSchema mySchema;
string resourceName = "MyEmbeddedSchema.xsd";
string resourcesFolderName = "Serialisation";
string manifestResourceName = string.Format("{0}.{1}.{2}",
this.GetType().Namespace, resourcesFolderName, resourceName);
using (Stream schemaStream = currentAssembly.GetManifestResourceStream(manifestResourceName))
mySchema = XmlSchema.Read(schemaStream, errorHandler);
请参阅:如何获取程序集的命名空间?
编辑:还注意到我正在回答的问题有一个非常详细的答案,位于http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3a469f5d-8f55-4b25-ac25-4778f260bb7e
另一个编辑,以防有相同问题的人寻找:在此处解决资源加载问题的出色思路:如何获取项目csproj(VS 2008)的默认命名空间
不可能。没有指定“Root”名称空间。选项中的默认命名空间是Visual Studio的东西,而不是 .net 的东西。
我刚刚创建了一个名为Root的空内部类,并将其放在项目根目录(假设这是您的根名称空间)。然后,我在需要根名称空间的任何地方都使用它:
typeof(Root).Namespace;
我最后会得到一个未使用的文件,但它是干净的。
在给定的程序集中可能存在任意数量的命名空间,它们并不要求都从一个公共的根开始。最好的方法是反射程序集中所有类型,并构建一个包含其中唯一命名空间的列表。
程序集不一定有根命名空间。 命名空间和程序集是正交的。
您可能正在寻找的是在该程序集中查找类型,然后找出其命名空间。
您可以使用GetExportedTypes()成员来完成此操作,然后从返回的Type句柄之一使用Namespace属性。
但同样不能保证所有类型都在同一个命名空间中(甚至不在同一个命名空间层次结构中)。
我在我的WPF应用程序中使用typeof(App).Namespace
。
App类对于任何WPF应用程序都是必需的,并且位于根目录中。
GetType(frm).Namespace
frm
是启动窗体。
命名空间与程序集无关 - 命名空间和程序集中的类之间的任何映射都纯粹是由命名约定(或巧合)决定的。
public static string? GetDefaultNamespace(this Assembly assembly, double threshold = 0.8)
{
var types = assembly.GetTypes();
int partIndex = 0;
var parts = new List<string>();
var ranked = types
.Where(_ => _.Namespace != null)
.GroupBy(_ => _.Namespace)
.Select(_ => new { Parts = _.Key!.Split('.'), Count = _.Count() })
.Where(_ => _.Parts.Length > partIndex)
.GroupBy(_ => _.Parts[partIndex])
.OrderByDescending(_ => _.Sum(x => x.Count))
.ToArray();
while (ranked.Any() && ranked[0].Sum(_ => _.Count) >= types.Length * threshold)
{
parts.Add(ranked[0].Key);
partIndex++;
ranked = ranked[0]
.Where(_ => _.Parts.Length > partIndex)
.GroupBy(_ => _.Parts[partIndex])
.OrderByDescending(_ => _.Sum(x => x.Count))
.ToArray();
}
return string.Join('.', parts);
}