【问题标题】:Applying Unity in dynamic menu在动态菜单中应用 Unity
【发布时间】:2010-04-25 12:04:35
【问题描述】:

我正在查看 Unity 2.0 以检查它是否在我们的新应用程序中有效。我的应用程序是一个 Windows 窗体应用程序,目前使用传统的条形菜单(在顶部)。

我的 UI(Windows 窗体)或多或少地支持依赖注入模式,因为它们都使用通过构造函数提供给它们的类(Presentation Model Class)。然后表单绑定到提供的 P Model 类的属性并调用 P Model 类上的方法来执行其职责。非常简单明了。

P 模型如何响应 UI 操作并通过与域类(业务逻辑/模型)协调来响应它们在这里无关紧要,因此没有提及。

从菜单中显示一个 UI 的对象创建顺序如下 -

  1. 创建业务模型实例
  2. 创建演示模型实例,并将业务模型实例传递给 P 模型构造函数。
  3. 创建 UI 实例,并将 Presentation Model 实例传递给 UI 构造函数。

我目前的解决方案:

要在上面的方法中从我的菜单中显示 UI,我必须从我的 Menu 类中引用所有程序集(Business、PModel、UI)。考虑到我已将模块拆分为多个物理程序集,要添加对大约 60 个不同程序集的引用将是一项艰巨的任务。此外,该方法的可扩展性不是很高,因为我肯定需要发布更多模块,并且使用这种方法,每次发布新模块时我都必须更改源代码。

所以主要是为了避免从我的菜单类(程序集)中引用这么多程序集,我做了如下 -

将上述所有依赖项存储在数据库表(SQL Server)中,例如

ModuleShortCode | BModelAssembly | BModelFullTypeName | PModelAssembly | PModelFullTypeName | UIAssembly | UIFullTypeName

现在使用了一个名为“Launcher”的静态类,其方法为“Launch”,如下所示 -

Launcher.Launch("Discount");
Launcher.Launch("Customers");

Launcher 在内部使用依赖表中的数据并使用 Activator.CreateInstance() 来创建每个对象,并将该实例用作正在创建的下一个对象的构造函数参数,直到构建 UI。 UI 随即显示为模式对话框。 Launcher 里面的代码有点像 -

Form frm = ResolveForm("Discount");
frm.ShowDialog();`

ResolveForm 完成了构建对象链的技巧。

Unity 可以在这里帮助我吗?

现在,当我这样做时,我没有足够的关于 Unity 的信息,现在我研究了 Unity,我想我或多或少都在做同样的事情。所以我尝试用 Unity 替换我的代码。

但是,我一开始就遇到了障碍。如果我尝试将菜单中的 UI 表单解析为

Form customers = myUnityContainer.Resolve<Customers>();

Form customers = myUnityContainer.Resolve(typeof(Customers));

无论哪种方式,我都需要从我的菜单程序集中引用我的 UI 程序集,因为 Unity 需要知道目标类型“客户”才能解决它。所以我回到了同一个地方,因为我必须从菜单程序集中引用所有 UI 程序集。我知道,使用 Unity,我将不得不引用更少的程序集(仅 UI 程序集),但需要这些引用,这违背了我的以下目标 -

  1. 动态创建对象链,无需来自菜单程序集的任何程序集引用。这是为了避免每次发布新模块时都会更改菜单源代码。我的菜单也是根据表格动态构建的。

  2. 只需提供新程序集并通过数据库补丁在表中插入新的 Dependency 行,即可提供新模块。

在这个阶段,我有一种感觉,我必须按照我的方式去做,即 Activator.CreateInstance() 来实现我的所有目标。我需要验证社区是否与我的想法相同或有更好的建议来解决问题。

这篇文章真的很长,如果你能到这里,我真诚地感谢你。期待您的宝贵建议。

  • 拉贾什

【问题讨论】:

    标签: unity-container


    【解决方案1】:

    我可以从这段代码中看到

    Form customers = myUnityContainer.Resolve<Customers>();
    

    您的所有代码都需要了解客户 - 它是一个 Form 类。因此,如果您使用 xml 配置进行统一,您可以执行以下操作:

     <type type="Form" mapTo="Customer"  name="Customer">
     </type>
    

    然后你就可以像这样解决它:

    Form customers = myUnityContainer.Resolve<Form>("Customer");
    

    并且无需引用您的 UI 程序集。当然,它应该出现在 bin 目录或 GAC 中。在这种情况下,如果您要开发新的程序集 - 您只需更改配置并放入 bin 或 gac。

    如果您想从 db 进行统一配置,那么您必须添加对您的 ui 的引用,因为您必须调用 Register("Customer")。

    【讨论】:

    • 太棒了!这是我忽略的一个有趣的信息。没有时间测试,但它应该工作。非常感谢。
    • 之前没来得及检查代码,现在检查。它工作顺利。它解决了引用过多程序集和交付新程序集的主要难题。谢谢。
    猜你喜欢
    • 2020-02-20
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多