Подтвердить что ты не робот

Как получить корневое пространство имен сборки?

Для экземпляра System.Reflection.Assembly.

4b9b3361

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

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

Ответ 5

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

typeof(Root).Namespace;

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

Ответ 6

GetType(frm).Namespace

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

Ответ 7

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

Ответ 8

Пространства имен не имеют ничего общего с сборками - любое сопоставление между пространством имен и классами в сборке происходит исключительно из-за соглашения об именах (или совпадения).

Ответ 9

Фактически есть косвенный способ получить его, перечисляя имена ресурсов манифеста сборки. Имя, которое вы хотите, заканчивается той частью, которую вы знаете.

Вместо того, чтобы повторять код здесь, см. получить имя пространства имен по умолчанию для метода Assembly.GetManifestResourceStream()

Ответ 10

Я использую typeof(App).Namespace в своем приложении WPF. Класс App является обязательным для любого приложения WPF и расположен в корне.

Ответ 11

Вопрос, который у меня был, приземлил меня здесь: "Если я вызову библиотечный код 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;
    }

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

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

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

Ответ 12

Добавляя ко всем остальным ответам здесь, надеюсь, без повторения информации, вот как я решил это использовать 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
        )
)

Ответ 13

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

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