如何设置具有winforms和web项目的解决方案?

时间:2011-05-12 08:51:10

标签: c# visual-studio design-patterns

在我的解决方案中,我有几个项目:

  • 核心项目。该项目包含我的所有类和接口
  • Winforms项目
  • 一个Web项目

该应用程序的一个关键功能是动态生成控件。我有一个带枚举的类,并且基于枚举值,必须返回特定的控件。所以我在核心项目中创建了一个像这样的工厂:

public IControl Create(Enum enum)
{
    switch(enum)
    {
      case "enum.A":
        return new CheckBoxControl();
      case "enum.B":
        return new RadioControl();
    }
}

你可能已经猜到了,我有自定义控件。它们都继承自Interface(IControl)。但在这种情况下,CheckBoxControl和RadioControl是WinFroms控件。

现在,这些控件位于核心项目中。我不想要这个,因为它是一个核心库,我希望这个库与平台无关。

我想要WinCore项目中的winforms控件和WebCore项目中的WebControls。问题是,我如何从核心项目中返回正确的控件?

WebCore和WinCore项目都需要对核心项目的引用,因为核心项目包含我的实体。这意味着,我无法从web或wincore项目的核心设置引用。

如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

我会这样做:

  • 。核心 应该是包含商家的程序集

  • .Shared 应该是一个包含基础架构,基类和接口的程序集,这些程序是平台和技术无关的 - 所以这可以让你在任何项目中引用它,避免不必要的依赖 -

  • .Web 应该是包含面向网络功能的程序集

  • .Web.Forms 应该是仅包含Web窗体和Web控件的程序集

  • .Windows 应该是包含面向Windows功能的程序集。

  • .Windows.Forms 应该是仅包含Windows窗体和控件的程序集。

具有这样的组装结构,IControl接口应该在 .Shared 程序集中,这应该由 .Core 引用,允许代码添加IControl实例而无需特定于技术的依赖关系。

此外,此解决方案足以让 .Windows .Windows.Forms .Web .Web。表格参考。核心和/或。分享


<击>更新

<击>

这只是一个建议,但为什么你在工厂使用枚举?你可以这样做:

public TControl Create<TControl>() where TControl : IControl, new()
{
    IControl control = new TControl();

    // Control initialization work

    return control;
}

你怎么看?

没关系,这只是一个建议,因为通过一些重构,你可以使用这种工厂方法,但我可以理解这远非你当前的实现。在我的回答中集中精力:)


更新2:

控制反转如何帮助您解决问题?

事实上,如果您注册控制组件的反转,您将按类型或某些唯一标识访问它们。

假设你有IControl接口(服务),WindowsTextBox和WebFormsTextBox都实现了IControl。在您的配置文件中,您将拥有两个组件,这两个组件具有相同的服务类型(接口)和两个不同的实现,并且这些组件将标记有两个不同的标识符:

  • WindowsTextBox是IControl,标识符为 WindowsTextBox
  • WebFormsTextBox是IControl,标识符为 WebFormsTextBox

现在你已经在控制容器的反转中注册了两个控件,你可以像这样使用自己的API组件检索工厂:

  • IoCFactory.GetComponents<IControl>()。您希望所有 IControl 实现在控件容器的当前反转中 - 在您的情况下不推荐! -

  • IoCFactory.GetComponent<IControl>("WindowsTextBox")。您需要名为“WindowsTextBox”的 IControl 实现。

在第二种情况下,我们现在关注的是,您可以获得一个类型为 IControl 的对象,这意味着您可以访问其常用成员(属性,方法,事件......)。

问题的控制反转在哪里?请注意,您使用的是工厂类,该类将放置在共享库中,以便您可以在任何地方使用它,对于 IControl 界面也是如此。

是的,我想你需要具体的控制实例。你可以做两件事:

  • 只需使用 IControl 实例,无论在何处,在特定于技术的逻辑中,将其转换为具体类型 - 例如, WindowsTextBox - 然后继续

  • 创建具有更多 IControl 的接口,因此某些逻辑可以访问更接近具体控件功能集的某些属性和方法。 一个例子是 ITextBox 接口,通过这个更具体的界面得到控制组件的任何反转,就像我上面解释的那样

我相信我提供了足够的提示,以便了解我的解决方案结构和装配组织以及控制反转如何能够为您提供您在项目层之间和之间寻找的技术独立性! ;)

答案 1 :(得分:0)

使用RegisterControls方法将Controlmanager添加到核心。 Webcore调用Controlmanager.RegisterControls方法。主应用程序只与核心

进行对话

答案 2 :(得分:0)

您应该在WinForms项目和Web项目中使用不同的工厂。创建在两个工厂中实现的IControlFactory接口,并在每个项目中实例化相应类型的工厂。