我正在尝试在我的新项目 Windows 窗体 C# 应用程序中使用模型- View - Controller -模式。
我的项目分为几个子项目:
Core
UI (View)
Controller
Model
Services
Helper
Tests
项目依赖如下:
我的 UI 项目包含 2 个表单,ListForm 和 AddForm(还有其他表单,但这些与此问题无关)。
现在,如果用户单击 ListForm 内的 Add-Button,我希望显示 AddForm。
但是,如果 Controller 甚至不知道 UI 项目,我如何在 Controller 内创建 AddForm 的新实例?
我尝试使用服务,但由于服务必须知道 UI 项目才能创建实例,因此我会有循环依赖(根据 Visual Studio)。
如果用户单击 ListForm 内的 Add-Button,我如何显示 AddForm?
(每次最多显示 1 个 AddForm)。
最佳答案
一种可能的方法涉及 Controller 工厂。工厂负责创建 Controller 和 View 并将两者连接在一起。
工厂应该是可配置的,所以你可以对不同的 View 集有不同的实现 - 用于构建实际 ui 的一组 View 有自己的工厂,另一个测试集有另一个工厂等。所有工厂都通过相同的 api 访问以便您仅在必要时重新配置工厂。实现这种工厂的一种可能方法是使用 IoC 容器,它可以简化实现,但不是必需的。使用 IoC 容器,您只需注册 View 的不同实现,并可以重用工厂的相同实现,而没有 IoC 容器,您将需要为每组 View 额外实现工厂。
然后您的父 Controller 使用工厂创建子 Controller 的实例。工厂返回子 Controller 并注入(inject)适当的 View 。父 Controller 调用子 Controller 上的 ShowView
,这只是使 View 可见,或者子 Controller 甚至可以在创建时自动显示 View 。
编辑:创建 Controller / View 的示例工厂:
在 Controller 层:
public interface IControllerFactory
{
TController CreateControllerAndView<TController>()
where TController : Controller;
}
public class ControllerFactory
{
// actual provider
private static IControllerFactory _provider;
// factory method
public static TController
CreateControllerAndView<TController>() where T : Controller
{
return _provider.CreateController<TController>();
}
public static void SetProvider( IControllerFactory provider )
{
_provider = provider;
}
}
任何时候你想创建一个新的 Controller ,你都可以引用工厂:
var controller = ControllerFactory.CreateControllerAndView<UserController>();
请注意,工厂不依赖于任何东西,它只是被定义,尚未实现。
然后,在最上层的某个地方,可能是在启动项目中,您实现了一个具体的提供者:
public class ConcreteControllerFactory : IControllerFactory
{
public TController CreateControllerAndView<TController>()
{
// since you are in the top most layer, you know all types from
// underlaying layers, including controllers and views
// IoC would help here a lot! But without it:
if ( typeof<TController> == typeof<UserController> )
{
IUserView view = new UIUserView();
UserController c = new UserController( view );
}
...
}
}
然后在某个地方
ControllerFactory.SetProvider( new ConcreteControllerFactory() );
通过这种方式,您可以将任何特定提供程序插入工厂、测试提供程序、ui 提供程序等。实际实现可能会有所不同,但您应该明白这一点。
关于c# - 如何在MVC-Pattern中管理多个表单,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20453684/