代码之家  ›  专栏  ›  技术社区  ›  Dmitri Nesteruk

如何创建具有热交换功能的松耦合体系结构?

  •  3
  • Dmitri Nesteruk  · 技术社区  · 14 年前

    我有兴趣创建一个由模块组成的桌面应用程序,这样 这些模块嵌入在应用程序本身中,允许用户在运行应用程序时编辑应用程序,并在不重新启动应用程序的情况下使用更新的模块。有人能为这个建议一个好的架构吗?

    我想用微软的.Net和C。DLR不是一个选项。

    谢谢!

    3 回复  |  直到 14 年前
        1
  •  2
  •   Falcon    14 年前

    在一篇简短的文章中,要为这个问题提出一个好的架构并不容易。

    首先,我定义一个契约(一个接口),用户编写/修改的每个模块都必须实现。它至少应该包含一个Execute方法。

    1. 从文件加载源代码
    2. 包装器编译文件,并确保它实现契约
    3. 包含是否可以成功编译文件的指示器
    4. 它还应该执行合同,以便打电话和处理

    然后我会得到一个包含所有模块包装器集合的shell。任何成功编译的包装器都会让Shell调用模块接口的Execute方法。

    在动态编译和执行代码时,此链接应提供所需的所有信息: http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm

        2
  •  0
  •   Mark Seemann    14 年前

    好吧,一种充满活力的语言肯定是最合适的。。。

    您可以使用 System.Reflection.Emit

    然而, 因为您需要将这些动态程序集加载到自定义应用程序域中,否则将无法再次卸载它们。

    这再次意味着您必须解决与跨AppDomain通信相关的封送处理和程序集解析问题。

        3
  •  -1
  •   Patrick    14 年前

    您可能正在寻找的是依赖注入的概念。

    有几种实现依赖注入的方法。一种方法是引用每个模块中的接口,并显式地让应用程序使用接口的正确实现配置其每个模块。

    实现它的第二个方法(在您的情况下可能是最有用的方法)是使用中央注册表。定义要在应用程序中包含的所有接口。这些是要为其动态更改实现的接口。然后定义这些接口的标识。这些可以是字符串、整数或GUID。

    std::map<std::string,IInterface> appInterfaces;
    appInterfaces["database"] = new OracleDatabaseModule();
    appInterfaces["userinterface"] = new VistaStyleUserInterface();
    

    使所有模块在需要使用其中一个模块时都转到这个中心注册表。确保它们不直接访问模块,但它们只通过注册表传递。例如。

    MyModule::someMethod()
    {
    IDatabaseInterface *dbInterface = dynamic_cast<IDatabaseInterface *>(appInterfaces["database"]);
    dbInterface->executeQuery(...);
    }
    

    如果现在要更改应用程序中接口的实现,只需更改注册表中的条目,如下所示:

    IInterface *iface = appInterfaces["database"];
    if (iface) delete iface;
    appInterface["database"] = new SqlServerDatabaseInterface();