Выполнить метод другого пространства имен по динамическому коду в 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); 
Другие вопросы по тегам