• 信息系统开发平台OpenExpressApp - 从compositewpf到MEF


      在信息系统开发平台OpenExpressApp - 发布for .Net4版本中介绍过现在从以前的compositewpf改为.Net4自带的MEF来作为扩展应用机制,MEF的主要架构可以通过之前写的.Net4下的MEF(Managed Extensibility Framework) 架构简介来简单了解一下,对于compositewpf不了解的可以去参考它的官方网站。本篇我将介绍一下OpenExpressApp升级到for .Net4版本时如何从从compositewpf更改到MEF,想了解MEF的简单应用的也可以看看。

    compositewpf的应用

      compositewpf在OpenExpressApp for .Net3的应用主要有模块装载以及界面组合两个应用,下面分别介绍一下这两方面之前如何实现的,后面会介绍这两部分如何在MEF下实现。

    模块加载

    •    在【OpenExpressApp.Host.WPF】项目的【Bootstrapper.cs】单元中通过重载GetModuleCatalog来获取模块目录
    protected override IModuleCatalog GetModuleCatalog()
    {
    ModuleCatalog catalog
    = new ModuleCatalog();
    //制定装载OpenExpressApp模块
    catalog.AddModule(typeof(ExpressAppModule));

    //从目录装载
    Directory.CreateDirectory(@".\Module");
    var dirCatalog
    = new DirectoryModuleCatalog() { ModulePath = @".\Module" };
    dirCatalog.Initialize();
    foreach (var module in dirCatalog.Modules)
    {
    catalog.AddModule(module);
    }
    //等业务模块加载完毕在加载OpenExpressApp.Module.WPF模块。否则提前创建的DefaultOpen模块没有按钮。
    catalog.AddModule(typeof(WPFModule));
    return catalog;
    }
    • 具体模块从IModule继承下来,并实现Initialize方法
    public abstract class XXXModule :  Microsoft.Practices.Composite.Modularity.IModule
    {
    #region IModule Members
      public virtual void Initialize()
    { ......
    }


    UI组合

    • 【OpenExpressApp.Host.WPF】中的【DockableContentRegionAdapter.cs】和【DockableRegionAdapter.cs】增加两个Region适配器
    • 在Shell.xaml中注册Region:

    <AvalonDock:DockingManager x:Name="_dockingManager" >
    <AvalonDock:ResizingPanel>
    <AvalonDock:DockablePane AvalonDock:ResizingPanel.ResizeWidth="228">
    <AvalonDock:DockableContent cal:RegionManager.RegionName="Tools" Title="模块列表"/>
    </AvalonDock:DockablePane>
    <AvalonDock:ResizingPanel Orientation="Vertical">
    <AvalonDock:DocumentPane cal:RegionManager.RegionName="Workspace"/>
    <AvalonDock:DockablePane cal:RegionManager.RegionName="Pads"/>
    </AvalonDock:ResizingPanel>
    </AvalonDock:ResizingPanel>
    </AvalonDock:DockingManager>

    • 在【OpenExpressApp.Module.WPF】项目的【WPFModule.cs】单元的初始化函数中增加控件到相应的Region
     this._regionManager.RegisterViewWithRegion(ShellRegionNames.Tools, typeof(ModuleListPad));
    • 在【Application.cs】中的打开模块中把生成的模块显示在指定工作区域
    public static object OpenModule(Type boType)
    {
    var regions
    = GetRegions();
    IRegion moduleRegion
    = regions[ShellRegionNames.Tools];
    IRegion mainRegion
    = regions[ShellRegionNames.Workspace];
    var modulePad
    = moduleRegion.ActiveViews.First() as ModuleListPad;
    BusinessObjectInfo selectItem
    = GetModule(boType, modulePad);
    Debug.Assert(selectItem
    != null, "未找到这个模块,不能打开!");
    //左边的控件
    modulePad.lbModule.SelectedItem = selectItem;

    //右边的控件
    object view = CreateView(mainRegion, selectItem);

    //日志
    AuditLogService.LogAsync(new AuditLogItem()
    {
    Title
    = "打开模块:" + selectItem.Label,
    ModuleName
    = selectItem.Label,
    Type
    = AuditLogType.OpenModule
    });

    return view;
    }
            private static object CreateView(IRegion mainRegion, BusinessObjectInfo selectItem)
            {
                object view = null;

                 //如果已经打开则激活模块,否则新增模块窗体
                if (OpenModules.TryGetValue(selectItem.BOType, out view) == false)
                {
                    if (selectItem.ModuleUIType != null)
                    {
                        view = Activator.CreateInstance(selectItem.ModuleUIType);
                    }
                    else
                    {
                        view = CreateModuleForm(selectItem);
                    }


                  mainRegion.Add(view); //添加到区域

                    OpenModules.Add(selectItem.BOType, view);
                }


                mainRegion.Activate(view);


                return view;
            }

    MEF的应用

    1. 从compositewpf转移到MEF,首先去除以前项目对Microsoft.Practices.XXX等项目的引用,加入对【System.ComponentModel.Composition】的引用来试用MEF
    2. 由于不用UI组合功能,删除【DockableContentRegionAdapter.cs】、【DockableRegionAdapter.cs】、【Bootstrapper.cs】
    3. 修改【App.xaml.cs】,不了解MEF基础的可以去网上搜索一下资料来学习一下
       private bool Compose()
      {
      var catalog
      = new AggregateCatalog();
      //添加模块程序集目录
        catalog.Catalogs.Add(
      new AssemblyCatalog(Assembly.GetExecutingAssembly()));
      catalog.Catalogs.Add(
      new AssemblyCatalog(
      Assembly.GetAssembly(
      typeof(OpenExpressApp.Module.ExpressAppModule))));
      catalog.Catalogs.Add(
      new AssemblyCatalog(
      Assembly.GetAssembly(
      typeof(OpenExpressApp.Module.WPF.SystemModule.WPFModule))));
      if (Directory.Exists(@".\Module")) catalog.Catalogs.Add(new DirectoryCatalog(@".\Module"));
      _container
      = new CompositionContainer(catalog);
      _container.ComposeExportedValue
      <CompositionContainer>(_container);
      //执行模块的初始化,注意:这里的IModule接口是在OpenExpressApp.Library中实现的
      var modules
      = _container.GetExportedValues<IModule>();
      foreach (var module in modules)
      {
      module.Initialize();
      }

      CompositionBatch batch
      = new CompositionBatch();
      batch.AddPart(
      this);
      _container.Compose(batch);

      return
      true;
      }

      在App()中启动

        if (Compose())
      {
      //Application.Current.Run(_container.GetExportedValue<Window>("OpenExpressApp.MainWindow"));
      _container.GetExportedValue<Window>("OpenExpressApp.MainWindow").Show();
      }
    4. 删除【Shell.xaml】中的Region设定,在【Shell.xaml.cs】中Export一些需要扩展的UI
      [Export(ContractName.MainWindow, typeof(Window))]
      public partial class Shell : Window, IPartImportsSatisfiedNotification
      {

      [Export(ContractName.Pads,
      typeof(ItemsControl))]
      public ItemsControl Pads
      {
      get
      {
      return Pads;
      }
      }

      [Export(ContractName.Workspace,
      typeof(IWorkspace))]
      private DocumentPaneWorkSpace _Workspace
      {
      get
      {
      return new DocumentPaneWorkSpace(workspace);
      }
      }
    5. 在【Shell.xaml.cs】中Import工具面板
      public partial class Shell : Window, IPartImportsSatisfiedNotification
      {
      [ImportMany(ContractName.Tools)]
      public IEnumerable<Control> Tools { get; set; }

      public void OnImportsSatisfied() //实现IPartImportsSatisfiedNotification,组合完毕后执行
      {
      foreach (var item in Tools)
      this.tools.Items.Add(new DockableContent() { Content = item });
      }
    6. 打开模块
      在【WPFModule】中Import组合容器CompositionContainer并赋值给OpenApplication.CompositionContainer
      [Export(typeof(IModule))]
      public class WPFModule : AdaptCommandModule
      {
      [Import]
      private CompositionContainer _compositionContainer = null;

      /// <summary>
      /// 把ModuleListPad.xaml加入到region中。
      ///
      /// 加入ComboDataGrid.xaml到Resource中
      /// </summary>
      public override void Initialize()
      {
      base.Initialize();

      OpenApplication.CompositionContainer
      = _compositionContainer;

      在【OpenExpressApp.Module.WPF】的【Application.cs】中的【OpenApplication】类增加区域属性
      public static IWorkspace Workspace
      {
      get
      {
      return CompositionContainer.GetExportedValue<IWorkspace>(ContractName.Workspace);
      }
      }

      public static Control ModuleListPad
      {
      get
      {
      return CompositionContainer.GetExportedValue<Control>(ContractName.ModuleListPad);
      }
      }


      public static ItemsControl Pads
      {
      get
      {
      return CompositionContainer.GetExportedValue<ItemsControl>(ContractName.Pads);
      }
      }

      public static Selector ModuleListBox
      {
      get
      {
      return CompositionContainer.GetExportedValue<Selector>(ContractName.ModuleListBox);
      }
      }

      以上是迁移的主要修改部分,具体细节请大家去下载代码 信息系统开发平台OpenExpressApp - 发布for .Net4版本

    更多内容: 开源信息系统开发平台之OpenExpressApp框架.pdf

    欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]

        [Export(ContractName.MainWindow, typeof(Window))]
        public partial class Shell : Window, IPartImportsSatisfiedNotification
        {
  • 相关阅读:
    AcWing 199. 余数之和
    AcWing 295. 清理班次
    AcWing 294. 计算重复
    Acwing 393. 雇佣收银员
    AcWing 362. 区间
    AcWing 361. 观光奶牛
    CSP-S 2019 Emiya 家今天的饭
    CSP-S 2019游记
    AcWing 345. 牛站 Cow Relays
    java 环境配置
  • 原文地址:https://www.cnblogs.com/zhoujg/p/1745308.html
Copyright © 2020-2023  润新知