Проекты

.NET Compiler

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

Полученная сборка компилируется в текущем домене. Благодаря этому, нет проблем с доступом ко всему приложению. При этом, есть вариант напакостить и сломать само приложение, так что пользоваться лучше с осторожностью. Соответственно, при перекомпиляции кода, старая сборка остаётся в контексте запущенного приложения.

UI

В левой панели — список подгруженных сборок. При двойном нажатии на пространство имён (namesapce), оно добавляется в using класса. При нажатии кнопки на тулбаре «Reference», откроется окно добавления новой сборки в проект. (Возможна подгрузка ссылки на сборку из: GAC, Файловой системы, Массива плагинов) Или список ранее добавленных сборок и используемых пространств имён.

Нажатие на кнопку «Full Source», позволяет отобразить весь код класса. По умолчанию, код класса скрыт и для редактирования доступен только динамически вызываемый метод класса. Чтобы вернуть вид редактирования одного метода класса, дополнительный код необходимо будет почитстить вручную.

По кнопке «Inclide Debug Info», можно скомпилировать сборку с .pdb файлом.

Затем идёт выбор языка компиляции и версия фреймворка. Эти параметры я беру из глубин .NET'а, так что необязательно что во всех вариантах будет доступна комиляция или выбор языка. По кнопке «Compile», можо скомпилить и проверить созданный метод и при ошибках компиляции, снизу появится список с сообщениями об ошибках. Пока, при тестировании метода доступны только пустые аргументы вызова.

Открыть окно

Для вызова окна редактирования метода, необходимо передать 2 параметра: Идентификатор выхываемого метода и ключ или идентификатор метода, который будет скомпилирован. За сохранность кода отвечает сам плагин компиляции.

//Description of the caller plugin
IPluginDescription thisPlugin = this.PluginDescription;

//Key for a new method
String methodName = "GetSomeCookies";


IWindow window = this.HostWindows.Windows.CreateWindow("425f8b0c-f049-44ee-8375-4cc874d6bf94",
	"Plugin.Compiler.DocumentCompiler",
	false,
	new KeyValuePair<String, Object>("CallerPluginId", thisPlugin.ID),
	new KeyValuePair<String, Object>("ClassName", methodName));

Скомпилировать и выполнить метод

Для вызова метода, вкупе с идентификаторами плагина и ключом метода, необходимо передать массив параметров. Для примера, представим что наш метод принимает один входящий параметр типа String.

//Description of the caller plugin
IPluginDescription thisPlugin = this.PluginDescription;

//Key for a new method
String methodName = "GetSomeCookies";

Some input value for the GetSomeCookie(String) method
String value = "I want cookie";


IPluginDescription plugin = this.Window.Plugin.Host.Plugins["425f8b0c-f049-44ee-8375-4cc874d6bf94"];
Object result;

if(plugin == null) {
	this.Trace.TraceEvent(TraceEventType.Warning, 5, "Compiler plugin '425f8b0c-f049-44ee-8375-4cc874d6bf94' not installed");
} else
{
	IPluginMethodInfo member = plugin.GetMember("InvokeDynamicMethod");
	if(member == null)
		throw new ArgumentNullException("Method 'InvokeDynamicMethod' not found in plugin '425f8b0c-f049-44ee-8375-4cc874d6bf94'");
	result = member.Invoke(
		thisPlugin,
		methodName,
		new Object[] { value, });
}
Теги:

Скачать

Ссылки

Родительские файлы