Как получить ссылку на экземпляр объекта из динамически создаваемого класса - PullRequest
3 голосов
/ 15 декабря 2010

В моем приложении C # у меня есть объект, например, для.свойства Color и Size, и его заполнение из значений в дБ.

Затем у меня есть приложение-дизайнер, которое позволяет пользователю добавлять код C # / VB (целый класс с конкретными методами), который может или можетне использовать / не изменять значения из свойств объекта

Когда приложение запускается, в памяти будет создан класс (codeprovider) из строки, созданной приложением дизайнера, и особый метод (отражение) во время выполнения

Как разрешить методу динамического кода ссылаться на мой объект (не статичный и заполненный данными, специфичными для пользователя), чтобы, если пользователь добавил код, например:

if(TheObject.Color == "Blue")
    TheObject.Width="150";

, я мог получить егосработает, если я передам объект методу динамического класса в качестве входного параметра:

....
ocResults = oCodeProvider,CompileAssemblyFromSource(oCParams, userCode);
oAssy = oCResults.CompiledAssembly;
oExecInstance = oAssy.CreateInstance("userClass");
oType = oExecInstance.GetType();
oType.GetMethod("OnLoad", new Type[] { typeof(myObj) });

, но не могу понять, куда поместить объект, чтобы динамический код мог ссылаться на него (динамический код будетгенерируется и выполняется для каждого пользователя, но они должны ссылаться на объект, созданный для их сеанса.

Код пользователя должен быть простым для написания и не иметьчтобы получить ссылку от например.static Dictionary<String,Object> (на который ссылается код пользователя AppDic["UserName"].Color), а затем снова удалить его из словаря при выполнении динамического кода.

Код пользователя должен быть просто: TheObject.Color (как статический метод)поскольку пользовательскому коду не нужно создавать экземпляр, код, создающий динамический код, уже заполнил значения свойств. Пользователь должен иметь возможность только изменять / читать);

Кто-нибудь может помочь?

1 Ответ

1 голос
/ 16 декабря 2010

По сути, как только вы нашли MethodInfo, который вы хотите на Type, который вы создали из кода пользователя, не возникает проблем с простой отправкой ему объекта в качестве параметра.Как в:

object userType = ... // compile user's code, load user's type from compiled assembly
MethodInfo myMethod = ... // find the wanted method on the user's type

// assuming the user code is in a static method to avoid having to create instances.
myMethod.Invoke(null, targetObj); 

Если вы хотите, чтобы пользователю нужно было только написать:

theObject.Color;

Затем вы должны обернуть код пользователя, чтобы получить что-то вроде этого:

// BEGIN PREFIX
public static class UserType
{
    public static UserMethod(TheObject theObject);
    {
// END PREFIX, user code follows

theObject.Color = Color.Red;

// BEGIN SUFFIX
    }
}
// END SUFFIX

Кстати, у выбранной вами конструкции есть некоторые серьезные последствия для безопасности.

Например, ничто не может помешать пользовательскому коду выполнить действия, которые приведут к прекращению работы вашего приложения, перестанут отвечать на запросы,или другие вещи.Преднамеренно или нет.Например, если пользователь вводит что-то вроде System.Windows.Forms.Application.Exit();, вы ничего не можете сделать.

Решением таких уязвимостей было бы запустить код пользователя в отдельном AppDomain и отправить ему целевой объект, например, через Remoting.

Редактировать: Попытка предложить способ, который не требует передачи объекта в качестве параметра.

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

public class TheInstance
{
    public static TheObject TheObject = new TheObject();
}

Так что теперь пользовательский код сможет делать такие вещи, как:

TheInstance.TheObject.Color = Color.Red;

И вам не придется беспокоиться об отправке параметра.

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

Это то, что вы искали?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...