【问题标题】:PRISM: Are PRISM Modules intended to have only one view per region?PRISM:PRISM 模块是否旨在每个区域只有一个视图?
【发布时间】:2011-03-31 02:05:47
【问题描述】:

我真的很困惑模块中应该包含什么。

当我为许多视图调用 RegisterViewWithRegion 时,它们都在模块初始化期间一起加载...所有这些视图都旨在托管在同一区域内,因为它们是同一模块的不同进程。

假设我有一个名为 Inventory 的模块,它包含一个产品视图、一个订单视图等。所有这些都与一个名为“MainRegion”的区域相关联,我想在以下情况下实例化这些视图用户请求它们,而不是在模块初始化时。

在我看来,这个谜的唯一答案是 Prism 模块旨在(我称之为)内部只有一个进程,所以这样我最终会得到不同的模块,如下所示:

Inventory.Products.xap

Inventory.Orders.xap

...等等。

对吗? 是否有任何替代方法可以让我将这些流程放在一个模块中?在这种情况下,这样方便吗?

提前致谢! 让·保罗

【问题讨论】:

    标签: silverlight views prism modularity regions


    【解决方案1】:

    Prism 区分实例化视图和显示视图。 Prism 4 有一个用于按需显示区域的新 API,但也可以使用旧版本进行按需显示。除非您的视图是资源密集型的,否则我建议在引导时加载它们,然后根据用户的要求显示它们。

    这里有几篇文章应该会有所帮助:

    Prism 4.0 Display-on-Demand

    Display-on-Demand - Older Versions of Prism

    【讨论】:

    • 谢谢大卫!...是的,我的视图实例化了一个 Viewmodel,而这个 VM 实例化了一个 UnitOfWork,其中包含几个查找列表和安全相关的对象...这就是为什么我不喜欢他们得到的事实在模块初始化时实例化...
    【解决方案2】:

    补充一下@David 所说的,Prism 可以帮助您在逻辑上分离不同的模块,并且将每个视图分离到其自己的模块是 (a) 一个巨大的矫枉过正,以及 (b) 一个糟糕的架构。

    良好的架构知道如何划分和征服应用程序的任务,这意味着知道何时划分事物,有时甚至更重要的是,何时不划分事物

    【讨论】:

    • 问题是一个模块不应该包含超过一个相同区域的视图,除非第二个视图将从第一个视图实例化。据我了解这个概念,模块是与系统中的一个特定功能相关的一组视图,以及可以从它们各自的父级访问的一些子视图。对吗?
    • 我自己说得再好不过了 :)
    【解决方案3】:

    好吧,我想我终于明白它应该如何工作了。

    为了为这篇文章打下基础,假设应用程序模块(不是 prism 模块)是与业务流程中的特定活动相关的视图(以前称为表单)和过程的集合,例如:销售,库存,银行业务......等。

    在每个应用程序模块中,我们会找到诸如 Sales.Invoices、Sales.Orders、Inventory.Products、Inventory.Stocks 等流程。

    现在,正如@Elad 所说,在 prism 中,为应用程序模块内的每个进程创建一个新项目可能是一个巨大的矫枉过正,正如 @David 所说,Prism 区分了实例化视图和显示它。

    好吧,为了做正确的事(那就是听这些家伙的话),我决定这样做:

    1) 将 Visual Studio 项目与 Prism 模块区分开来: 在你的解决方案中,没有必要将应用模块分解成不同的项目,你需要做的就是通过“应用模块”创建一个项目

    2) 在每个“应用程序模块”项目中创建不同的模块初始化器类,每个进程一个,例如:

    对于 MyApplicationModule 中的进程“A”:

          <ModuleExport(GetType(MyApplicationModule.ProcessAInitializer))> _
        Public Class ProcessAInitializer
            Implements IModule
    
            <Import()> _
            Public Property RegionManager As IRegionManager
    
    
        #Region "IModule Implementation"
            Public Sub Initialize() 
                       Implements Microsoft.Practices.Prism.Modularity.IModule.Initialize
                RegionManager.RegisterViewWithRegion(RegionNames.SubMenuView, 
                                GetType(MyApplicationModule.SubMenuViewA))
                RegionManager.RegisterViewWithRegion(RegionNames.ContentRegion,
                                GetType(MyApplicationModule.ContentViewA))
            End Sub
        #End Region
        End Class
    

    对于 MyApplicationModule 中的进程“B”:

    <ModuleExport(GetType(MyApplicationModule.ProcessBInitializer))> _
    Public Class ProcessBInitializer
        Implements IModule
    
        <Import()> _
        Public Property RegionManager As IRegionManager
    
    
    #Region "IModule Implementation"
        Public Sub Initialize() 
                Implements Microsoft.Practices.Prism.Modularity.IModule.Initialize
            RegionManager.RegisterViewWithRegion(RegionNames.SubMenuView,
                              GetType(MyApplicationModule.SubMenuViewB))
            RegionManager.RegisterViewWithRegion(RegionNames.ContentRegion,
                              GetType(MyApplicationModule.ContentViewB))
        End Sub
    #End Region
    End Class
    

    3) 一旦我们得到这个,让我们稍微改变一下你的模块目录是如何在你的 shell 项目中创建的。在我的例子中,我使用代码一个一个地添加 Prism 模块,你可以从文件中加载模块定义,但原理是一样的:

    Protected Overrides Function CreateModuleCatalog() As 
                              Microsoft.Practices.Prism.Modularity.IModuleCatalog
        Dim objModuleCatalog = New ModuleCatalog
       objModuleCatalog.AddModule(New ModuleInfo() 
                                  With {.InitializationMode = InitializationMode.OnDemand,
                                        .Ref = "MyApplicationModule.xap",
                                        .ModuleType = "MyApplicationModule.ProcessAInitializer, MyApplicationModules, Version 1.0.0.0, Culture=neutral, PublicKeyToken=null",
                                        .ModuleName = "ProcessAInitializer"})
    
       objModuleCatalog.AddModule(New ModuleInfo() 
                                  With {.InitializationMode = InitializationMode.OnDemand,
                                        .Ref = "MyApplicationModule.xap",
                                        .ModuleType = "MyApplicationModule.ProcessBInitializer, MyApplicationModule, Version 1.0.0.0, Culture=neutral, PublicKeyToken=null",
                                        .ModuleName = "ProcessBInitializer"})
        Return objModuleCatalog
    End Function
    

    结论

    这样,只有当用户请求这个特定的“业务流程”时,您的视图才会被实例化,您不需要将解决方案拆分成更小的部分,因此它需要永远编译并且您的解决方案仍然是“团队友好的”。

    谢谢@David 和@Elad

    【讨论】:

      猜你喜欢
      • 2012-04-24
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      • 2015-07-08
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多