2010-12-15 8 views
3

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

Тогда у меня есть дизайнер приложение, которое позволяет пользователю добавлять 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) }); 

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

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

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

Может ли кто-нибудь помочь?

+3

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

+0

Обновленный вопрос – DeWet

+1

'TheObject' черт! У меня есть класс с этим именем. – Andrey

ответ

1

В принципе, как только вы нашли 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); 

Если вы хотите, чтобы пользователь имел только writa:

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 для компиляции кода пользователя.

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

+0

Не слишком беспокоит пользовательский код, нарушающий приложение. Все изменения будут записаны и поскольку это будет использоваться в качестве бизнес-приложения, сотрудник, который «сломал» систему, будет рассмотрен :) Я использую метод входных параметров в настоящее время oType.GetMethod («OnLoad», новый тип [] {typeof (myObj)}); , но просто подумал, что должен быть способ выставить объект из другого места, чтобы получить тот же результат в введенном вами коде пользователя: theObject.Color = Color.Red; – DeWet

+0

Kinda, но вот почему я изначально разместил вопрос ....... что произойдет, если моя система будет использовать, скажем, 5000 одновременных пользователей? Не будут ли они перезаписывать друг друга в TheInstance.TheObject, что приведет к сбою кода пользователя? – DeWet

Смежные вопросы