如何从动态创建的类中引用对象的实例

时间:2010-12-15 07:20:13

标签: c# .net reflection dynamic

在我的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(就像静态方法一样,因为用户代码不需要创建实例,创建动态代码的代码已经填充了属性值。用户必须只能够改变/阅读);

有人可以帮忙吗?

1 个答案:

答案 0 :(得分: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); 

如果您希望用户只需要写:

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编译用户代码时将此程序集指定为引用。

那是你在找什么?