Как получить корневое пространство имен сборки? - PullRequest
38 голосов
/ 19 сентября 2008

Учитывая экземпляр System.Reflection.Assembly.

Ответы [ 13 ]

56 голосов
/ 07 июня 2011

Я много раз сталкивался с этой дилеммой, когда хочу загрузить ресурс из текущей сборки его потоком манифеста.

Дело в том, что если вы встраиваете файл в качестве ресурса в сборку с помощью 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)

38 голосов
/ 19 сентября 2008

Не возможно. Ничто не указывает на пространство имен "Root". Пространство имен по умолчанию в опциях - это визуальная студия, а не .net

10 голосов
/ 19 сентября 2008

В данной сборке может быть любое количество пространств имен, и ничто не требует, чтобы все они начинались с общего корня. Лучшее, что вы можете сделать, - это отразить все типы в сборке и составить список содержащихся в ней уникальных пространств имен.

5 голосов
/ 19 сентября 2008

Сборки не обязательно имеют корневое пространство имен. Пространства имен и сборки ортогональны.

Вместо этого вы можете найти в этой сборке тип, а затем выяснить, каково его пространство имен.

Этого можно добиться, используя член GetExportedTypes (), а затем используя свойство Namespace из одного из возвращенных дескрипторов Type.

Опять же, нет никаких гарантий, что все типы находятся в одном и том же пространстве имен (или даже в одной иерархии пространства имен).

4 голосов
/ 11 ноября 2015

Я только что создал пустой внутренний класс с именем Root и поместил его в корневой каталог проекта (предполагая, что это ваше корневое пространство имен). Затем я использую это везде, где мне нужно корневое пространство имен:

typeof(Root).Namespace;

Конечно, я получаю неиспользуемый файл, но он чистый.

2 голосов
/ 01 июля 2014
GetType(frm).Namespace

frm это форма запуска

1 голос
/ 19 сентября 2008

Получить типы дает список Тип объектов, определенных в сборке. Этот объект имеет свойство пространства имен. Помните, что сборка может иметь несколько пространств имен.

0 голосов
/ 08 июня 2017

Здесь представлен довольно простой способ получения корневого пространства имен для проекта веб-сайта.

''' <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» и возвращает корневое пространство имен для этого типа. Это полезно для регистрации, когда у вас есть несколько веб-проектов в одном решении, совместно использующем систему журналов. Надеюсь, это кому-нибудь поможет.

0 голосов
/ 22 февраля 2017

Добавление ко всем остальным ответам здесь, надеюсь, без повторения информации, вот как я решил это с помощью Linq. Моя ситуация похожа на ответ Лизы.

Мое решение имеет следующие предостережения:

  • Вы используете Visual Studio и для своего проекта определено корневое пространство имен, которое, как я полагаю, является тем, о чем вы просите, поскольку вы используете термин "корневое пространство имен"
  • Вы не встраиваете типы взаимодействия из сборок, на которые есть ссылки
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
        )
)
0 голосов
/ 09 мая 2016

Вопрос, который у меня возник, заключался в следующем: «Если я вызываю библиотечный код N методов глубоко и хочу получить пространство имен проекта - например, приложение MVC, которое на самом деле работает - как мне это получить?»

Немного хакер, но вы можете просто взять трассировку стека и отфильтровать:

    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;
    }

Все, что это делает, - получает трассировку стека, запускает методы из самых последних вызванных в root и фильтрует систему. Как только он находит системный вызов, он знает, что он зашел слишком далеко, и возвращает вам пространство имен непосредственно над ним. Независимо от того, запускаете ли вы модульный тест, приложение MVC или службу, контейнер System будет находиться на 1 уровень глубже корневого пространства имен вашего проекта, так что вуаля.

В некоторых случаях, когда системный код является промежуточным звеном (например, System.Task) на трассе, это может дать неправильный ответ. Моя цель состояла в том, чтобы взять, например, некоторый код запуска и позволить ему легко найти класс или контроллер или что-то еще в корневом пространстве имен, даже если код, выполняющий работу, находится в библиотеке. Это решает эту задачу.

Я уверен, что это можно улучшить - я уверен, что этот хакерский способ действий можно улучшить многими способами, и улучшения приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...