3

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

Например, в обычных условиях, когда я запустить веб-сайт 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

Сортировка. См. Http://msdn.microsoft.com/en-us/library/bb398860.aspx#PreCompilingToFixedNameAssemblies. Я предпочитаю веб-приложения, так как это поведение намного лучше определено. То, что вы хотите сделать, тривиально в проекте веб-приложения. – dash

ответ

4

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

При составлении проекта есть MSDN article on using the -fixednames flag.

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

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

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

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

EDIT: В качестве дополнения к комментариям; если я использую инструмент «Опубликовать веб-инструмент», тогда весь код в app_code отправляется в каталог bin в dll, называемом App_Code.dll, - это поведение не меняется, даже если я использую фиксированное именование (все фиксированные именования влияют на имена DLL для каждой странице, usercontrol).Если я использую ILSpy в этом файле, я могу видеть мои классы там. Поэтому я знаю название сборки, и это место - я должен с минимальными усилиями получить типы в нем. Интересно, почему я вижу для тебя другое поведение!

Я создал простой класс под названием «Человек» с Ид и имя, поместите его в App_Code, составленный сайт, а затем побежал следующий код:

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

Он написал «Персона», как ожидается.

Далее Edit

Пенни падает! Если бы я тогда делать:

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.

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

+0

В фоновой информации я заметил, что, как вы предполагали, возможна отдельная сборка, но я пытаюсь понять, могу ли я обойтись без нее. Не все DLL-файлы находятся в папке bin на веб-сайте, поэтому я не решаюсь перечислить файлы ASP.NET Temp, но вы правы, что кеширование информации для последующего использования является оптимизированной возможностью. В первом предположении, даже если на веб-страницах были известны имена сборки, я все еще не могу динамически загружать класс app_code (не на веб-странице) по имени строки из-за того же обстоятельства - можете ли вы предоставить более ясную информацию об фиксированном имени Я мог бы не понимать эффект на app_code. –

+0

Я только что построил свой ответ для полноты - я считаю, что ввод кода в отдельную сборку - это правильный ответ в этом случае, но мне очень интересно то, что вы пытаетесь сделать (отличный вопрос!). Прошло некоторое время с тех пор, как я использовал проект веб-сайта (мне не нравятся их по многим причинам), но я пойду посмотреть на один из наших ранних проектов, так как я уверен, что я пробовал что-то в этом направлении. – dash

+0

@JohnK Я обновил свой ответ экспериментом, который я только что пробовал. – dash