2009-11-19 2 views
4

Как .NET найти DLL пространства имен Я using? Да, мы упоминаем путь в/referene: c: \ program files **, но после создания & развертывания и когда программное обеспечение установлено на какой-либо машине пользователя. Возможно, это не так, как я сказал (разработчик). Я имею в виду, что это может быть где-то еще?Как .NET найти DLL пространства имен, которое я использую?

  1. Итак, как .NET находит его?
  2. Как .NET знает во время выполнения все пространства имен в DLL?
  3. Что делать, если пользователь имеет одну и ту же DLL, но он переименовал его? Может ли .net не загружать его?

ответ

6

Вы можете увидеть различные действия в действии, если вы запустите fuslogvw.exe (из .NET SDK) и включите ведение журнала всех привязок на диск. Вы сможете увидеть различные пути, которые .NET CLR использует для разрешения ссылок на сборки. Однако правило состоит в том, чтобы сначала попробовать глобальный кэш сборок, а затем проверить локальный каталог вместе с несколькими другими альтернативными путями.

+0

Это звучит интересно, но когда я запустил «Инструменты Windows SDK> Fusion log viewer», каждая кнопка отключается в этом окне. В диалоговом окне настроек все отключено. – claws

+0

Если вы используете Vista или Windows 7 с включенным UAC, вы должны запустить его из командной строки с повышенными правами, потому что для изменения настроек регистрации фьюжн необходимы административные привилегии. – Josh

+0

«Правило большого пальца, однако, должно сначала попробовать глобальный кэш сборок, а затем проверить локальный каталог вместе с кучей других альтернативных путей». Скажем, если я установил «.NET MYSQL CONNECTOR» (используя MySql.Data). Используя ссылки во время компиляции, он обнаруживает DLL, но его путь будет чем-то вроде c: \ programfiles \ mysql \ .net \ mysql.dll, но после того, как приложение будет построено, а какое-то другое его использует. все мое приложение знает, что это его mysql.dll, но на usermachine это.сетевой разъем может быть установлен на d: \ apps \ somecrap \ mysql.dll. Тогда как обнаружить clr? – claws

3

Названия сборок и пространств имен не связаны между собой понятия.

Скомпилированный сборник ссылок на другие сборки, содержащие их name.

Когда сборка загружена, ее ссылки загружаются путем поиска имени, как описано here. Наиболее общим местом для сборки является Global Assembly Cache машины и базовый каталог приложения.

После загрузки сборки и всех ее ссылок (и ссылок на ссылки и т. Д.) Среда выполнения загружает требуемые типы из сборок.

Например, если вы используете тип String как в

using System; 

... 
String x = "Hello World"; 

компилятор С # смотрит String и решает его к System.String типа в mscorlib сборки, и преобразует код на нечто похожее на это:

[mscorlib]System.String x = "Hello World"; 

Таким образом, когда выполняется оператор среда выполнения знает, как полное имя типа System.String и имя сборки, содержащей тип.

+0

Скомпилированные сборки также могут ссылаться на другие сборки слабыми именами. –

5

Технически, в DLL нет пространств имен.

На уровне CLR вообще нет пространств имен, только полные имена классов. Имя класса CLR может состоять из произвольно длинной последовательности любых символов Юникода - например, @#$% будет отличным именем класса, что касается CLR.

Теперь по соглашению (CLS, быть конкретными), имена классов ограничены определенными Unicode символами (буквенно-цифровых символов и _, и куча других экзотических Unicode категорий - см спецификации для получения дополнительной информации) и точкой, и точка используется для обозначения пространств имен. Это чисто соглашение между компиляторами (и другими инструментами).

Таким образом, всякий раз, когда сборка ссылается на какой-либо тип по какой-либо причине, он просто использует свое полное имя CLR, например System.String. Но есть больше - на самом деле, он использует полное имя, которое также включает сборку.Вы можете увидеть их, если посмотрите на вывод ildasm - они выглядят примерно как [mscorlib]System.String, поэтому среда выполнения знает, где искать.

Иными словами, CLR действительно видит сборку mscorlib.dll, имеющую класс System.String, и сборку B.exe, ссылающуюся на этот класс как [mscorlib]System.String. Ваш оператор using не генерирует никакого кода в выходной DLL/EXE самостоятельно; это просто так, что вам не нужно писать System.String все время.

Это работа компилятора перевести свой код, говорящий String, в области видимости using System; заявления, в проекте, который ссылается mscorlib.dll, к [mscorlib]System.String. Все это делается во время компиляции. Единственное, что CLR делает во время выполнения, - это разрешить mscorlib, чтобы найти фактическую mscorlib.dll на диске (а другой ответ объясняет, как именно это происходит).

+0

Как это решить из System.String в [mscorlib] System.String Как узнать его в сборке mscorlib? System.String - довольно распространенный тип. Как насчет некоторых пользовательских сторонних типов. Как компилятор узнает, в какой сборке находится этот класс? – claws

+1

Он будет заглядывать во все сборки, на которые ссылается проект, который вы компилируете (или указан с помощью '/ r:' в командной строке). Если две сборки, с которыми вы ссылаетесь, определяют класс с именем 'System.String', вы получите ошибку компилятора (но вы можете обойти это в C#, используя« extern alias »для устранения неоднозначности сборок). –

+0

«Единственное, что CLR делает во время выполнения, - это разрешить mscorlib, чтобы найти фактическую mscorlib.dll на диске». --- Скажем, если я установил «.NET MYSQL CONNECTOR» (используя MySql.Data). Используя ссылки во время компиляции, он обнаруживает DLL, но его путь будет чем-то вроде c: \ programfiles \ mysql \ .net \ mysql.dll, но после того, как приложение будет построено, а какое-то другое его использует. все мое приложение знает, что его этот mysql.dll, но на usermachine этот .net-коннектор может быть установлен на d: \ apps \ somecrap \ mysql.dll. Тогда как это можно обнаружить? это то, что мой первоначальный вопрос, если я не был ясен. – claws

Смежные вопросы