Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何设置包含winforms和web项目的解决方案?_C#_Visual Studio_Design Patterns - Fatal编程技术网

C# 如何设置包含winforms和web项目的解决方案?

C# 如何设置包含winforms和web项目的解决方案?,c#,visual-studio,design-patterns,C#,Visual Studio,Design Patterns,在我的解决方案中,我有几个项目: 核心项目。此项目包含我的所有类和接口 Winforms项目 网络项目 应用程序的一个关键特性是动态生成控件。我有一个带有枚举的类,并且必须基于枚举值返回一个特定的控件。因此,我在核心项目中创建了一个工厂,如下所示: public IControl Create(Enum enum) { switch(enum) { case "enum.A": return new CheckBoxControl();

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

  • 核心项目。此项目包含我的所有类和接口
  • Winforms项目
  • 网络项目
应用程序的一个关键特性是动态生成控件。我有一个带有枚举的类,并且必须基于枚举值返回一个特定的控件。因此,我在核心项目中创建了一个工厂,如下所示:

public IControl Create(Enum enum)
{
    switch(enum)
    {
      case "enum.A":
        return new CheckBoxControl();
      case "enum.B":
        return new RadioControl();
    }
}
你可能猜到了,我有自定义控件。它们都从接口(IControl)继承。但在本例中,CheckBoxControl和RadioControl是WinFroms控件

现在,这些控件驻留在核心项目中。我不想要这个,因为它是一个核心库,我希望这个库独立于平台

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

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


如何解决此问题?

使用方法RegisterControl向core添加一个Controlmanager。Webcore调用Controlmanager.RegisterControl方法。主应用程序只与core对话

我会这样做:

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

    // Control initialization work

    return control;
}
  • .Core应该是包含业务的程序集

  • .Shared应该是一个包含基础结构、基类和接口的程序集,这些基础结构、基类和接口独立于平台和技术,因此这将允许您在任何项目中引用它,避免不必要的依赖关系

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

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

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

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

有了这样的汇编结构,IControl接口应该位于.Shared汇编中,并且应该由.Core引用,允许代码添加IControl实例,而不需要特定于技术的依赖项

此外,此解决方案足以让.Windows.Windows.Forms.Web.Web.Forms引用.Core和/或.Shared


更新:

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

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

    // Control initialization work

    return control;
}
public TControl Create(),其中TControl:IControl,new()
{
IControl control=new TControl();
//控制初始化工作
返回控制;
}
你觉得怎么样

尽管如此,这只是一个建议,因为也许通过一些重构,您可以使用这种工厂方法,但我可以理解这与您当前的实现相去甚远。集中精力回答:)


更新2:

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

事实上,若您注册了控制组件的反转,您将按类型或某个唯一标识符访问它们

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

  • WindowsTextBox是IControl,标识符为WindowsTextBox
  • WebFormsTextBox是IControl,标识符为WebFormsTextBox
现在,两个控件都已在控件反转容器中注册,您可以使用自己的API组件检索工厂,如下所示:

public IControl Create(Enum enum)
{
    switch(enum)
    {
      case "enum.A":
        return new CheckBoxControl();
      case "enum.B":
        return new RadioControl();
    }
}
  • IoCFactory.GetComponents()
    。您希望所有的IControl实现都在当前反转控件的容器中-在您的情况下不建议这样做!-

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

在第二种情况下,这是我们现在关注的焦点,您将得到一个类型为IControl的对象,这意味着您可以访问它的公共成员(属性、方法、事件…)

你的问题的控制反转点在哪里?注意,您使用的是一个工厂类,该类将放置在共享库中,因此您可以在任何地方使用它,对于IControl接口也是如此

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

  • 只需使用IControl实例,在任何地方,以特定于技术的逻辑将其转换为具体类型(例如WindowsTextBox),然后继续

  • 创建尽可能多的接口来具体化更多的IControl,以便某些逻辑可以访问更接近于具体控件功能集的某些属性和方法。一个例子是一个ITextBox接口,并通过这个更具体的接口以我上面解释的相同方式获得控制组件的任何反转


我相信我已经给出了足够的提示,以便了解我的解决方案结构和组装组织,加上控制反转,如何为您提供这样的技术独立性,您可以在项目的层之间和层内进行查看!;)

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