Каковы этапы создания сборок, не зависящих от домена? - PullRequest
5 голосов
/ 17 июня 2010

... и могут ли эти шаги также применяться к сборке стороннего производителя (которая может быть уже со строгим именем)?

Контекст для моего вопроса не должен быть важным, но я все равно поделюсь: я подумываю сделать регистратор (или упаковщик журналов), который всегда знает, на какой «источник журналов» нужно ориентироваться, независимо от того, используются ли сборки использовать его можно в одном домене приложений или распределить по нескольким доменам приложений. Я думаю, что один из способов добиться этого - это иметь независимую от домена сборку со статическим свойством «LogSource». Если это статическое свойство установлено в независимой от домена сборке, я думаю, что все домены приложения увидят его.

Ответы [ 3 ]

14 голосов
/ 10 января 2013

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

То, как экземпляр CLR решает загрузить сборку, определяется политикой. Есть несколько способов явно установить эту политику:

  • set LoaderOptimizationAttribute в точке входа вашего исполняемого файла (обычно Main). Загрузчик CLR будет применять указанную политику при запуске исполняемого файла.
  • установить свойство AppDomainSetup.LoaderOptimization при создании нового домена приложения из управляемого кода.
  • CorBindToRuntimeEx - при запуске CLR из неуправляемого кода эта функция позволяет указать флаги запуска , некоторые из которых управляют оптимизацией загрузчика.

Сборка, загруженная как нейтральная к домену, будет загружена в общий домен. Доменное имя приложения - «EE Shared Assembly Repository» в CLRv4. Это не настоящий домен приложения, потому что он не имеет данных и не может запускать какой-либо код. Загруженные в него сборки будут делиться своим кодом среди всех других работающих доменов приложений. Байт-код в сборке будет JIT-скомпилирован только один раз. Однако все изменяемые данные в сборке будут дублироваться среди работающих доменов. Статические поля не являются общими для доменов приложений. Статические поля для доменов приложений будут дублироваться, и разные домены приложений будут читать и записывать в разных местах в памяти при обращении к одному и тому же статическому полю.

Помимо: есть еще один вид статических полей - статика RVA, которые являются общими для всех доменов приложения в текущем процессе. Невозможно объявить такое поле в C #, но это можно сделать в C ++ / CLI.

Существует компромисс в использовании нейтральных к домену сборок. Доступ к статическим полям медленнее. Поскольку они имеют JIT-тэг только один раз, но могут иметь доступ к нескольким экземплярам статического поля для домена приложения, любой доступ к статическому полю проходит через дополнительную косвенную ссылку. Когда сборка загружается прямо в работающий домен, адрес статического поля может быть непосредственно встроен в код JIT. Однако когда код, скомпилированный в общую сборку, пытается получить доступ к статическому полю, он должен сначала загрузить контекст текущего домена, а затем найти в нем адрес статического поля для этого домена.

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

  • Если вы загружаете несколько доменов, которые по сути работают с одним и тем же кодом, вы захотите как можно больше делиться сборками, если только это существенно не снижает производительность доступа к статическим полям. Примером является приложение, которое решает запустить части своего собственного кода в отдельном домене приложения для изоляции.
  • Если вы загружаете несколько доменов с разным кодом, вы захотите поделиться только теми сборками, которые обычно используются всеми различными сборками. Обычно это будут собственные сборки .NET Framework и все сборки, загруженные из GAC. IIS работает таким образом по умолчанию при запуске приложений ASP.NET.
  • Если вы когда-либо используете только один домен приложения, вам не следует ничего обмениваться. Обычное приложение с графическим интерфейсом будет таким.

Примечание: mscorlib всегда загружается в общий домен.

Источники и дальнейшее чтение:

3 голосов
/ 17 июня 2010

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

0 голосов
/ 23 июля 2014

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

http://geekswithblogs.net/akraus1/archive/2012/07/25/150301.aspx

...