Предоставить явное имя сборки для папки App_Code динамически скомпилированного веб-сайта ASP.NET? - PullRequest
3 голосов
/ 01 марта 2012

В динамически скомпилированном проекте веб-сайта ASP.NET можно ли явно указать сборку для папки App_Code?

Например, при обычных обстоятельствах, когда я запускаю веб-сайт ASP.NET, имя сборки, сгенерированное в папке Temporary ASP.NET Files\, частично рандомизируется, как App_Code.neizakfo.dll, где neizakfo - это часть, которая можетотличаются.Можно ли явно указать имя сборки, например App_Code_Web1.dll?

Пояснение

В соответствии с бизнес-требованиями, веб-сайт не может быть предварительно скомпилирован / развернут.Поэтому я ищу решение в контексте папки Temporary ASP.NET Files и динамически скомпилированных сборок, как отмечено выше.


Справочная информация :
Я сталкивался с этим вопросом, когда искал способ выполнения создания экземпляров динамического типа для класса в папке App_Code веб-сайта с использованием сборки, квалифицированнойимя хранится в конфигурации, но создается с веб-страницы, пересекая границу сборки.Поскольку веб-страница и код app_code по умолчанию скомпилированы в две разные сборки, стандартное поведение метода Type.GetType (..) при поиске имени типа в текущей исполняющей сборке (веб-странице) или в mscorlib не выполняется.достаточно для выбора любого типа из сборки App_Code.Будучи рандомизированным, имя сборки app_code мне неизвестно для включения в строку, соответствующую сборке.

Я могу поместить Тип данных в библиотеку классов (потому что у нее есть предопределенное / точное имя), чтобы избавиться от этой проблемы, однако я хотел бы знать, как сделать это внутри самого сайта безсоздание проекта библиотеки классов для этой цели.

1 Ответ

4 голосов
/ 01 марта 2012

Вы можете сделать это в проекте веб-сайта.

Есть статья MSDN об использовании флага -fixednames при компиляции проекта.

Это эффективно создает сборку для каждой страницы - default.aspx.dll.Тем не менее, это только немного более полезно для вас, так как вам все равно нужно знать имя элемента управления или страницы, которую вы ищете, когда вы загружаете - так что вы должны убедиться, что ваши типы и имена соответствуют.Однако он должен уважать имена классов в app_code, так что это может сработать для вас.

Еще одна вещь, которую вы можете сделать, это переместить весь код из app_code в его собственную сборку, а затем добавить этов качестве ссылки на проект.Это также упростило бы эту проблему.

Наконец, вы можете перечислить все библиотеки DLL в каталоге bin и найти каждый тип искомого типа.Поскольку это довольно дорого, сделайте это один раз и сохраните результат в кеше, чтобы вы не продолжали делать это каждый раз, когда просматриваете этот тип.Вероятно, это худшее решение.

Это тривиально в проекте WebApplication, но я полагаю, что вы застряли с сайтом WebSite?

РЕДАКТИРОВАТЬ: Какобновление для комментариев;если я использую Publish Web Tool, то весь код в app_code попадает в каталог bin в dll с именем App_Code.dll - это поведение не меняется, даже если я использую фиксированное именование (все фиксированные именования влияют на именование dll длякаждая страница, usercontrol).Если я использую ILSpy для этого файла, я могу видеть мои классы там.Итак, я знаю название сборки и ее местоположение - я должен быть в состоянии найти типы в ней с минимальными усилиями.Интересно, почему я вижу другое поведение для вас!

Я создал простой класс «Person» с идентификатором и именем, поместил его в App_Code, скомпилировал сайт, а затем запустил следующий код:

  Type myType = Assembly.LoadFrom(Server.MapPath("~/bin/App_Code.dll")).GetType("Person", true);
  Response.Write(myType.ToString());

В нем выписано «Лицо», как и ожидалось.

Далее Редактировать

Пенни падает!Если я затем сделаю:

  object myObject= Activator.CreateInstance("App_Code.dll", "Person");

и попытаюсь привести myObject к человеку, я получу следующее сообщение:

The type 'Person' exists in both 'App_Code.dll' and 'App_Code.jydjsaaa.dll '

Так что пришло время быть хитрым.

в Global.asax на Application_OnStart выполните следующее:

Application["App_Code_Assembly"] = Assembly.GetAssembly(typeof(Person));

На моей тестовой странице по умолчанию я сделал:

  Assembly app_Code = Application["App_Code_Assembly"] as Assembly;
  Response.Write(app_Code.FullName);

, что дало мнепроизвольно названный app_code, с которым он фактически работает во временных файлах ASP.Net.

Вот почему я ненавижу проекты веб-сайтов; -)

...