C#中基于插件的应用程序

时间:2009-06-25 13:32:51

标签: c# plugins

我必须使用我选择的语言制作图形用户界面应用程序。该应用程序将在Windows XP上运行。它将是某种复杂的Windows窗体应用程序。 我认为,根据大多数建议,C#将是最好用的。 GUI左侧的树结构将在从配置文件读取后填充,该配置文件将是二进制文件。 (但最初我可以用一个简单的ASCII文件来测试我的代码。)应用程序将通过此GUI接受来自用户的一些输入,并将其写回相同的配置文件,并将反映树形结构或标签或表单上任何其他相关字段的更改。

每个选项卡将有3个选项卡和3个相应的配置文件。 我现在需要一些帮助来设计应用程序。我打算制作一个主机应用程序(主应用程序)并使用3个选项卡控件作为插件。这可行吗?如果是这样,请指导我。我的意思是如何在C#中创建3个插件以及如何编写接口以便主应用程序知道要加载哪个插件以及何时加载它?我的项目文件夹下会有一个单独的“插件”文件夹吗?我希望你明白我的意思,虽然这对你来说太少了。

此外,项目中已存在一些.cpp文件。这些文件以及一些.h文件包含一些重要的定义和常量。这些需要与我的C#应用​​程序集成。我不知道如何做到这一点,但我确信通过在.dll中编译.cpp代码然后将编译的.dll暴露给我的C#应用​​程序是可能的。如果您需要有关顶级设计的更多信息,请与我们联系。

谢谢, Viren

5 个答案:

答案 0 :(得分:13)

要手动实现插件界面,您需要一个类似这样的方法。我已经留下了一些TODO,您可能希望增强错误处理和/或使实现更具特定于案例。

    public List<T> LoadPlugin<T>(string directory)
    {
        Type interfaceType = typeof(T);
        List<T> implementations = new List<T>();

        //TODO: perform checks to ensure type is valid

        foreach (var file in System.IO.Directory.GetFiles(directory))
        {
            //TODO: add proper file handling here and limit files to check
            //try/catch added in place of ensure files are not .dll
            try
            {
                foreach (var type in System.Reflection.Assembly.LoadFile(file).GetTypes())
                {
                    if (interfaceType.IsAssignableFrom(type) && interfaceType != type)
                    { 
                        //found class that implements interface
                        //TODO: perform additional checks to ensure any
                        //requirements not specified in interface
                        //ex: ensure type is a class, check for default constructor, etc
                        T instance = (T)Activator.CreateInstance(type);
                        implementations.Add(instance);
                    }
                }
            }
            catch { }
        }

        return implementations;
    }

致电示例:

List<IPlugin> plugins = LoadPlugin<IPlugin>(path);

至于问题的c ++部分。虽然正确的选择取决于您的具体情况,但您可以采用几种不同的方法。您可以在c ++中创建符合clr的.dll,您的c#项目可以像引用的任何其他.dll一样引用和调用。此外,您可以使用P/Invoke来调用本机.dll。

答案 1 :(得分:8)

我曾经使用的最简单的插件概念之一肯定是Managed Extensibility Framework,它将成为.NET 4(afaik)的一部分。不幸的是它还没有完成,只有预览可用,可能与最终版本不同。话虽这么说,我们使用MEF预览3进行单项目,它没有问题,它确实使整个插件更容易。

答案 2 :(得分:3)

查看System.Addin命名空间: http://msdn.microsoft.com/en-us/library/system.addin.aspx

否则你可以自己做所有事情。在此命名空间可用之前,我使用了一个通用接口“IPlugin”,每个插件/插件都需要使用。然后我有一个加载器检查文件夹中的所有* .dll然后使用反射来检查接口。然后我可以创建实现我的插件/插件接口的类的实例

cpp文件可能需要转换为c#,或者你可以创建一个dll来引用。

答案 3 :(得分:1)

看看Castle

答案 4 :(得分:0)

.NET Framework在其内部使用COM模型。有关使用此技术的插件示例列表,请参阅http://blog.caljacobson.com/2007/07/26/creating-a-plug-in-framework-in-c-resources/