Загрузка динамически созданного элемента управления ASCX (через код)

Я создаю Web User Controls с помощью кода (моя разметка записи кода C #, файлы кода программной части и файлы конструктора на диск при обратном вызове). Элементы управления созданы все в порядке. Я могу добавить их в свой веб-проект и разместить на странице.

Когда я пытаюсь загрузить элемент управления с помощью LoadControl(path), он говорит:

Unable to load type 'MyNameSpace.UseControlClass'

это потому, что элемент управления еще не скомпилирован.

Но мое требование - динамически загружать элементы управления без перекомпиляции решения.

Как я могу скомпилировать пользовательский элемент управления только при создании управляющих файлов? Поскольку это, кажется, единственный выход.

РЕДАКТИРОВАТЬ: - Я предполагаю, что, поскольку файл не скомпилирован, он не может быть загружен во время выполнения. Я попытался скомпилировать файл кода с помощью компилятора CodeDom. Нравится:

var filePath = Server.MapPath(path);
var provider = CSharpCodeProvider.CreateProvider("C#");
var opts = new CompilerParameters(new[] { "mscorlib.dll", "System.Web.dll", 
                              "Telerik.Web.Design.dll", "Telerik.Web.UI.dll", 
                              "Telerik.Web.UI.Skins.dll", "MyCurrentDll.dll"});
opts.GenerateExecutable = false;
opts.GenerateInMemory = true;
var cr = provider.CompileAssemblyFromFile(opts, new string[] { filePath+".cs" });

Но он жалуется на cannot find metadata file Telerik.Web.Design.dll и т. Д. Я не хочу жестко кодировать путь telerik, поскольку он может отличаться в размещенной системе (хотя он находится в bin текущего веб-приложения). Также MyCurrentDll.dll - это dll файла, из которого я компилирую файл кода. Как я могу это решить?

Моя идея состоит в том, чтобы скомпилировать файл кода, динамически создать dll и скопировать его в каталог bin веб-приложения. Это могло бы решить проблему, о которой я говорил изначально.

РЕДАКТИРОВАТЬ 2: - После пробной версии я могу динамически компилировать файл кода и генерировать dll. Даже после создания dll и помещения ее в bin моего приложения я не могу загрузить пользовательский элемент управления с помощью virtual path. Я пробовал следующий подход:

var asm = Assembly.Load("ddlPath");
var t = asm.GetType(fullTypeName);//NameSpace.Class
var ctrl = LoadControl(t,null);

После этого загружается ctrl. Я назначаю его свойство Id и добавляю его к asp.net Panel элементу управления. Но после постбека его не видно :(

Теперь мне нужно либо каким-то образом сделать динамически скомпилированные типы dll доступными для среды выполнения (возможно, appdomain), чтобы, когда я загружаю управление с использованием виртуального пути, он загружается правильно, и я не получаю HtmlParseException или не выясняю, почему загружается форма управления Type. не появляется.

PS: - Я загрузил Label элемент управления с помощью Type, и он работает правильно.


person TheVillageIdiot    schedule 19.04.2012    source источник
comment
Это действительно интересный вопрос. Я не могу придумать вариант использования для этого, но обычно я использую другую сборку, которая знает, как создавать элементы управления и генерирует HTML и т. Д. Во время выполнения. Возможно, здесь возможен аналогичный подход путем встраивания ваших новых элементов управления в другую сборку, которую вы затем можете скомпилировать и загрузить? Я буду смотреть этот вопрос с интересом!   -  person dash    schedule 19.04.2012
comment
@dash Сценарий использования состоит в том, что мы позволяем пользователю группировать некоторые поля (с предопределенными типами ввода) и получать данные от конечного пользователя. Я хочу создать пользовательский элемент управления, встраивая эти поля.   -  person TheVillageIdiot    schedule 19.04.2012
comment
Ваши элементы управления и хостинговая страница находятся в CodeFile, а не в CodeBehind?   -  person jbl    schedule 19.04.2012
comment
Пробовали ли вы поместить пользовательский элемент управления в другой проект в том же решении? Вы можете настроить вывод DLL в корзину в основном проекте.   -  person jlvaquero    schedule 19.04.2012
comment
@ user551263 как это сделать на веб-сайте, размещенном на сервере? @jbl Я не понимаю, о чем ты? Вы имеете в виду атрибуты CodeFile или CodeBehind в файле разметки пользовательского элемента управления?   -  person TheVillageIdiot    schedule 19.04.2012
comment
yahooooo! Готово, подробно опубликую о том, как это сделать позже.   -  person TheVillageIdiot    schedule 19.04.2012


Ответы (2)


В конце концов я смог решить проблему. Я принял следующую стратегию:

  1. Создавать текстовые файлы, содержащие структуру кода CodeBehind, Markup и Designer
  2. Прочтите информацию о том, какие поля создавать.
  3. Поместите разметку для элементов управления, необходимых в построителях строк.
  4. поместите некоторую другую связанную информацию в большее количество конструкторов строк
  5. Записывать файлы

После этого я создал dll с помощью компилятора CodeDome. Основная проблема, с которой столкнулись во время компиляции, как описано в части вопроса Edit, заключалась в том, что не удалось найти сборки, на которые есть ссылки, что было решено путем указания пути bin пути к каталогу вместе с именем файла dll, например:

Server.MapPath("~/bin")+"\\Telerik.Web.dll"

и Т. Д.

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

Даже после этого мне не удалось загрузить элемент управления на страницу, с которой я скомпилировал код. Это было решено, когда я загрузил элемент управления на другой странице. Среда выполнения смогла разрешить тип из динамически скомпилированного dll.

person TheVillageIdiot    schedule 20.04.2012

хмм .. думали ли вы об использовании папки App_Code для этой цели?

Содержит исходный код для общих классов и бизнес-объектов (например, файлов ..cs и .vb), которые вы хотите скомпилировать как часть своего приложения. В динамически скомпилированном проекте веб-сайта ASP.NET компилирует код в папке App_Code при первоначальном запросе к вашему приложению. Элементы в этой папке затем перекомпилируются при обнаружении каких-либо изменений.

person avs099    schedule 19.04.2012
comment
это мне не поможет, поскольку я создаю пользовательский элемент управления, а файлы также создаются динамически во время выполнения. проблема заключалась в загрузке созданных файлов в домен приложения для создания объекта управления. Я решил это и скоро отправлю ответ. - person TheVillageIdiot; 20.04.2012