编写高度用户可扩展的C#应用​​程序的最佳实践 [英] Best practice to write highly user extendable C# application

查看:76
本文介绍了编写高度用户可扩展的C#应用​​程序的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在一家从事微加工/精细力学研究的研究所,被要求为我们在一个实验室中使用的当前设置开发控制器软件.

I am currently at a research institute that does micromaching/fine mechanics and was asked to develop a controller software for the current setup we use in one of our labs.

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

We have a nano stage and some other equipment like shutters and filter wheels that should be controlled with a central application. The software provides pre-configured jobs for execution, which are basically algorithms that generate commands for the stage and are used to write different patterns with a laser into the samples (for example rectangles, cylinders, etc.)

现在,最好在运行时提供某种可能性来扩展此预定义作业列表,这意味着用户可以添加类似所提供算法的算法.

Now it would be great to provide some kind of possibility to extend this list of predefined jobs on runtime, which means that algorithms like the ones provided can be added by the user.

我是C#新手(通常是桌面应用程序新手),因此,如果您能给我一些有关如何完成此操作或应该从哪里开始的提示,我将万分感谢.

I'm a C# newbie (and a Desktop application newbie in general) so I am extremely thankful if you can give me some hints on how this could be done or where I should start looking.

推荐答案

我使用.NET集成的C#编译器完成了此脚本"操作. 这是一些工作,但基本上是这样的:

I did this 'script' thing using the .NET integrated C# compiler.
It is some work to do but basically is looks like this:

    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;
    }

真正的代码还有很多事情,包括代码编辑器.
多年来,它在我们的工厂中都运行良好.

The real code does a lot more things, including a code editor.
It works very well for years now in our factory.

通过这种方式,用户可以使用C#编写脚本,因此可以使用与您相同的API.

This way the users use C# for the scripts and can therefore use the same API as you do.

您可以使用看起来像普通.cs文件的代码模板.它是在运行时构建的,并提供给Compilesource参数.

You can use a code template that looks like a plain .cs file. It is build at runtime and provided to the source parameter of 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) { /* ... */ }
    }
}

示例:

string[] source = ??? // some code from TextBoxes, files or whatever, build with template file...
string[] references = new string[] { "A.dll", "B.dll" };

Assembly a = Compile(source, references);
object result = Execute(a, "MyCompany.Stuff.ScriptClass", "main");

这篇关于编写高度用户可扩展的C#应用​​程序的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆