编写高度用户可扩展C#应用程序的最佳实践

时间:2013-07-18 12:33:36

标签: c# winforms plugins

我目前在一家研究机构,负责微机械/精密机械,并被要求为我们在我们的一个实验室中使用的当前设置开发控制器软件。

我们有一个纳米级和一些其他设备,如百叶窗和滤光轮,应该用中央应用程序控制。该软件提供了预先配置的执行作业,基本上是为舞台生成命令的算法,用于将激光写入样本的不同模式(例如矩形,圆柱等)

现在提供在运行时扩展此预定义作业列表的某种可能性会很棒,这意味着用户可以添加所提供的算法。

我是C#新手(以及一般的桌面应用程序新手),所以我非常感谢你能给我一些关于如何做到这一点或者我应该从哪里开始寻找的提示。

1 个答案:

答案 0 :(得分:2)

我做了这个'脚本'使用.NET集成C#编译器的东西 这是一些工作,但基本上是这样的:

    public Assembly Compile(string[] source, string[] references) {
        CodeDomProvider provider = new CSharpCodeProvider();
        CompilerParameters cp = new CompilerParameters(references);
        cp.GenerateExecutable = false;
        cp.GenerateInMemory = true;
        cp.TreatWarningsAsErrors = false;

        try {
            CompilerResults res = provider.CompileAssemblyFromSource(cp, source);
            // ...
            return res.Errors.Count == 0 ? res.CompiledAssembly : null;
        }
        catch (Exception ex) {
            // ...
            return null;
        }
    }

    public object Execute(Assembly a, string className, string methodName) {
        Type t = a.GetType(className);
        if (t == null) throw new Exception("Type not found!");
        MethodInfo method = t.GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);          // Get method
        if (method == null) throw new Exception("Method '" + methodName + "' not found!");                                  // Method not found

        object instance =  Activator.CreateInstance(t, this);
        object ret = method.Invoke(instance, null); 
        return ret;
    }

真正的代码可以做很多事情,包括代码编辑器 它在我们的工厂已经很好地工作了很多年。

这样,用户可以使用C#作为脚本,因此可以使用与您相同的API。

您可以使用看似普通.cs文件的代码模板。它是在运行时构建的,并提供给source的{​​{1}}参数。

Compile

示例:

using System;
using System.IO;
using ...

namespace MyCompany.Stuff {
    public class ScriptClass {
        public object main() {

            // copy user code here
            // call your own methods here

        }

        // or copy user code here

        private int test(int x) { /* ... */ }
    }
}