如何获得程序集的根名称空间?
给定一个System.Reflection.Assembly
的实例。
不可能。 没有指定“根”名称空间。 选项中的默认命名空间是一个visual studio的东西,而不是.net的东西
当我想通过其清单资源stream从当前程序集加载资源时,遇到了这种困境。
事实是,如果使用Visual Studio将文件作为资源embedded到程序集中,则其清单资源名称将从Visual Studio项目中定义的程序集的默认名称空间派生而来。
我想出了最好的解决scheme(避免将默认名称空间作为string硬编码),只是简单地确保资源加载代码总是在类的内部发生,该类也在默认名称空间中,然后使用下面的通用方法可能用过了。
这个例子是加载一个embedded式模式。
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)的默认命名空间,
在一个给定的程序集中可能有任意数量的名字空间,没有要求它们都从一个公共根开始。 你可以做的最好的做法是反映程序集中的所有types,并build立其中包含的唯一名称空间的列表。
程序集不一定有根名称空间。 命名空间和程序集是正交的。
你可能正在寻找的是在这个Assembly中find一个types,然后找出它的名字空间是什么。
您应该可以通过使用GetExportedTypes()成员,然后使用返回的types句柄之一中的Namespace属性来完成此操作。
同样,不保证所有的types都在同一个命名空间中(甚至在相同的命名空间层次结构中)。
我只是创build了一个名为Root的空内部类,并把它放在项目根目录下(假设这是你的根名称空间)。 然后,我在任何地方都使用这个根名称空间:
typeof(Root).Namespace;
当然,我最终得到一个未使用的文件,但它很干净。
GetType(frm).Namespace
frm
是启动窗体
“获取types”提供了在程序集中定义的“ types”对象列表。 该对象具有名称空间属性。 请记住,程序集可以有多个名称空间。
命名空间与程序集无关 – 命名空间和程序集中的类之间的任何映射纯粹是由于命名约定(或巧合)。
实际上有一个间接的方法来获取它,通过枚举程序集的清单资源的名称。 你想要的名字以你知道的那部分结束。
请参阅获取Assembly.GetManifestResourceStream()方法的默认名称空间名称,而不是重复此处的代码
我在我的WPF应用程序中使用typeof(App).Namespace
。 应用程序类对于任何WPF应用程序都是必需的,它位于根目录中。
我把这个问题落在这里的问题是,“如果我深入调用库代码N的方法,并且需要项目的命名空间 – 例如实际运行的MVC应用程序,我该如何得到它?
有点哈克,但你可以抓住一个堆栈跟踪和filter:
public static string GetRootNamespace() { StackTrace stackTrace = new StackTrace(); StackFrame[] stackFrames = stackTrace.GetFrames(); string ns = null; foreach(var frame in stackFrames) { string _ns = frame.GetMethod().DeclaringType.Namespace; int indexPeriod = _ns.IndexOf('.'); string rootNs = _ns; if (indexPeriod > 0) rootNs = _ns.Substring(0, indexPeriod); if (rootNs == "System") break; ns = _ns; } return ns; }
所有这一切正在获取堆栈跟踪,从最近调用到根的方法,并过滤系统。 一旦它发现一个系统调用它知道它已经太过分了,并且返回它上面的命名空间。 无论你是在运行一个unit testing,一个MVC应用程序还是一个服务,系统容器将会比你的项目的根名字空间深1级,所以瞧。
在某些情况下,系统代码是一个中介(如System.Task)沿着跟踪,这将返回错误的答案。 我的目标是拿一些启动代码,让它很容易find一个类或控制器或任何在根名字空间,即使代码做的工作,坐在一个库。 这完成了这个任务。
我相信这一点可以改进 – 我敢肯定这种做事的方式可以在很多方面得到改善,而且我们也欢迎改进。
在这里添加所有其他的答案,希望没有重复的信息,这里是我如何使用Linq解决这个问题。 我的情况与Lisa的答案类似。
我的解决scheme有以下警告:
- 你正在使用Visual Studio,并且为你的项目定义了一个根名字空间,我假设你使用的术语是“root namespace”
- 您不是从引用的程序集中embeddedinteroptypes
Dim baseNamespace = String.Join("."c, Me.GetType().Assembly.ManifestModule.GetTypes(). Select(Function(type As Type) Return type.Namespace.Split("."c) End Function ). Aggregate(Function(seed As String(), splitNamespace As String()) Return seed.Intersect(splitNamespace).ToArray() End Function ) )
这里作为一个相当简单的方式来获取网站项目的根名称空间。
''' <summary> ''' Returns the namespace of the currently running website ''' </summary> Public Function GetWebsiteRootNamespace() As String For Each Asm In AppDomain.CurrentDomain.GetAssemblies() If Asm Is Nothing OrElse Asm.IsDynamic Then Continue For For Each Typ In Asm.GetTypes If Typ Is Nothing OrElse Typ.Name Is Nothing Then Continue For If Typ.Name = "MyProject" Then Return Typ.Namespace.Split("."c)(0) Next Next Return Nothing End Function
这只是检查所有加载的“MyProject”types的程序集,并返回该types的根名称空间。 当您在共享日志系统的单个解决scheme中有多个Web项目时,这对于日志logging非常有用。 希望这有助于某人。