2010-12-15 74 views
3

在我的C#应用​​程序中,我有一个例如对象。属性ColorSize,并从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) }); 

,但无法弄清楚在何处放置对象,以使动态代码可以参考它(动态代码将为每个用户生成并执行,但它们必须引用为其会话创建的对象。

该用户的代码应该很容易编写,而不必从一个例如。静态Dictionary<String,Object>(通过用户代码AppDic["UserName"].Color引用),然后在执行动态代码时从字典中再次将其删除。

用户代码应该只是:TheObject.Color(就像一个静态方法,因为用户代码不需要创建实例,创建动态代码的代码已经填充了属性值,用户只能够变化/读取);

任何人都可以帮忙吗?

+3

请正确格式化代码。另外,你问什么语言? – Robert 2010-12-15 07:22:59

+0

更新的问题 – DeWet 2010-12-15 12:31:19

+1

'TheObject'该死!我有这个名字上课。 – Andrey 2010-12-16 20:50:57

回答

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();之类的东西,则无法执行任何操作。

解决这些问题的方法是在单独的0123'中运行用户代码,并将目标对象发送给它,例如通过Remoting

编辑:试图建议一种方法,不需要传递对象作为参数。

你可以用一个类创建一个Assembly来暴露你的对象的静态实例。喜欢的东西:

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

所以,现在的用户代码就可以做这样的事情:

TheInstance.TheObject.Color = Color.Red; 

而且你不会有发送参数打扰。

为了让用户代码能够访问此程序集中的类,您只需在使用ICodeCompiler编译用户代码时将此程序集指定为引用。

这是你在找什么?

+0

不用担心破坏应用程序的用户代码。所有编辑都会被记录下来,因为这将用作商业应用程序,所以“打破”系统的员工将被处理:)我正在使用输入参数方法 oType.GetMethod(“OnLoad”,new Type [] {typeof(myObj)}); 但只是认为必须有一种方法来暴露对象从其他地方得到相同的结果在您发布的用户代码: theObject.Color = Color.Red; – DeWet 2010-12-16 21:12:50

+0

有点有点,但这就是我最初发布这个问题的原因.......如果我的系统被5000个并发用户使用,会发生什么?不会他们覆盖对方的TheInstance.TheObject导致用户代码失败? – DeWet 2010-12-17 00:55:34

相关问题