我有一个应用程序,其中有几个模块具有完全不同的功能,我正在尝试找出使用棱镜实现此功能的最佳方法。
为了尝试更好地解释,我将尝试使用Northwind作为示例。我有3个模块,订单,客户和员工。
客户模块将允许您执行与客户有关的任何事情。添加,删除和编辑。我将在客户模块的主视图中使用范围区域来处理我需要在此处显示的所有不同视图。
在上面的场景中,我只想在用户想要与客户,订单或员工合作时加载模块。
您已经制定了这些模块,并意识到您需要能够为明显是员工的客户或销售人员显示订单。
在这种情况下你会做什么,因为你不想为employeeOrders和customerOrders创建一个全新的模块,你不想复制任何与订单相关的代码。
我开始怀疑,如果您正在构建像Outlook这样的应用程序,是否可以考虑使用棱镜构建复合应用程序,但对于LOB业务应用程序,我还没有找到一个很好的示例如何要做到这一点,不要破坏MVVM的一些原则和Prism的定义。
我只有3个星期进入Prism并仍在学习,但这是我遇到的最大问题。
有什么想法吗?
答案 0 :(得分:1)
您应该将Event Aggregator用于这些类型的通信方案。实质上,您希望模块提供功能,但也要公开可以从其他模块调用的事件。您还可以在Unity容器中注册服务。例如:
public interface ICustomerOrderInvoker
{
void DisplayCustomerOrdersInRegion(string customerId, string regionName);
}
这些技术与MVVM有些正交。您的事件处理程序可以创建视图/视图模型对并将它们插入到区域中。或者您的事件处理程序可以创建一个UserControl,其中包含在代码后面实现的所有功能,并将其添加到区域。复合UI的优点在于您的模块可以使用MVVM,而另一个团队的模块可以使用直接用户控件或MVP或MVC或其他任何东西;关键是所有模块都组成一个应用程序而不管它们是如何实现的,因为它们使用Prism中建立的模式,如区域,事件等。
在您的特定情况下:
您已经制定了这些模块,并意识到您需要能够为明显是员工的客户或销售人员显示订单。
您的订单模块肯定会了解客户ID的概念,因为订单实体与客户相关联。 Order模块应该公开CompositePresentationEvent,它显示包含特定客户ID的所有订单的视图。
Prism的观点是创建逻辑上独立且松散耦合的功能。这并不意味着模块不相互通信,而是通信以有限且松散耦合的方式发生。您当然可以使用此模式和MVVM编写LOB应用程序;我们很多人已经多年了。 :)
答案 1 :(得分:0)
我正在处理类似的问题(也是Prism的新手),但还没有解决方案。我认为在使用Prism时,它很容易使用框架作为参考实现的意图,但它并不一定如此。
Prism应该(正确使用时)促进软件开发,而不是阻碍它。因此,不要过于担心任何实现必须满足严格的解耦重构超级模式化标准!
我正在做/打算做的是创建一个MainModule,它具有我的大部分核心功能,包括MainView / MainViewModel用户控件。然后Shell有一个区域“Main”,在MainModule加载时,MainView按照标准prism用法注入其中。
我在MainView上使用Telerik的Docking Manager(兼容Silverlight和WPF),并在Infrastructure中实现了一个类IDockingManager / DockingManager类,它在Unity中作为单例(ContainerControlledLifetimeManager)注册在引导程序中。
我的应用程序中的任何地方我都可以通过调用IDockingManager.DockView(IView视图,DockingParameters args)获取IDockingManager实例并注入视图。 DockingParameters可以包含诸如停靠位置(左,右,顶部,底部,选项卡式文档)以及要停靠的父容器等信息。
这是我还没有达到的部分 - 我可以在主视图上停靠左/右/上/下但是我想在我的子视图上实现附加属性或其他东西,当停靠时将它们注册为DockSite 。因此,例如,我可以将树视图停靠在左侧,并使用Treeview名称作为父级DockSite和DockBottom作为侧面停靠在列表视图下方。
希望这是有道理的,我在没有真正解释得太好的情况下絮絮叨叨。基本上我说的是我在这个应用程序中根本没有使用区域(除了注入MainView)并创建了一个类来处理可停靠容器中的视图注入。这不是严格的棱镜,但Prism可以让我的生活更轻松,而不是相反;)