Выполнить метод другого пространства имен по динамическому коду в C# winforms
Я реализую динамическое выполнение кода в C#, который позволяет пользователям писать свой собственный C# для этого конкретного приложения.
Я использую компилятор кода C# для выполнения динамических кодов. Компилятор C# читает файл кода и создает код в новом пространстве имен (полный новый код), компилирует и запускает его. С другой стороны, все эти базовые приложения хоста.
У меня есть несколько методов, которые присутствуют в хост-приложении, которые я хочу выполнять динамическим кодом. Есть ли способ, которым может быть выполнен метод другого пространства имен или приложения?
3 ответа
Не могли бы вы заставить автора вашего скрипта реализовать интерфейс, или вы могли бы даже обернуть их код своей собственной реализацией...
Что-то вроде
public interface IMyApplication
{
void DoSomethingInMyMainApp();
}
public interface IScriptKiddie
{
void Init(IMyApplication app);
}
Тогда ваши сценаристы l33t могут написать
public class MyScript : IScriptKiddie //< you could emit this yourself
{
public void Init(IMyApplication app) //<could emit this yourself if scripter knows app keyword
{
app.DoSomethingInMyMainApp();
}
}
и в вашем приложении вы можете предоставить конкретную реализацию IMyApplication для передачи в класс после компиляции, создания класса и передачи в метод Init.
Чтобы динамический код мог вызывать методы статического кода, вы должны предоставить необходимую ссылку при компиляции динамического кода.
Более подробно:
Скажем, у вас есть класс под названием MyClass
что вы хотите получить доступ из динамического кода. Положить MyClass
класс в отдельной сборке, назовем это MyAssembly
, Когда вы компилируете динамический код, одно из свойств ICodeCompiler
позволяет предоставлять сборки в качестве ссылок. Так что вы должны предоставить typeof(MyClass).Assembly
через это свойство.
Теперь, когда вы скомпилируете код, он сможет делать что-то вроде:
MyClass.CallSomeMethod();
Пространства имен здесь не проблема. Вы можете убедиться, что динамический код использует полное имя типа (например, MyNameSpace.MyClass
или вы можете сгенерировать using MyNamespace;
в начале динамического кода.
Наконец, я присоединяюсь к рекомендации Ричарда определить четкий интерфейс, который мог бы использовать динамический код. Вы просто должны предоставить сборку, содержащую этот интерфейс, в качестве ссылки при компиляции.
Вы можете использовать отражение. Что-то вроде этого:
Type objType = null;
objType = _Assemblies.GetType(className);
MethodInfo methodInfo = null;
methodInfo = objType.GetMethod(TheCommandString);
methodInfo.Invoke(objType, userParameters);