You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF+Prism框架下实现Application类多层继承复用的问题

刚好我最近在WPF+Prism项目里做了几乎一模一样的抽象复用,给你一套落地性很强的方案,完美匹配你想要的继承结构,还能把所有公共逻辑、资源、服务都抽离出来:

核心思路

把所有通用逻辑(Prism初始化、公共资源、共享服务/模块)封装到抽象的BaseApp中,具体应用只需要继承它并实现少量特定逻辑(注册自身模块/服务),完全符合你要的Application <-- BaseApp(抽象) <-- MySpecificApplication结构。

分步实现

1. 创建抽象的BaseApp(继承PrismApplication)

Prism本身提供了PrismApplication来替代原生WPF的Application,我们的抽象基类直接继承它,把所有公共逻辑都塞在这里:

using Prism.Ioc;
using Prism.Modularity;
using Prism.Regions;
using System.Windows;

public abstract class BaseApp : PrismApplication
{
    // 公共资源字典的路径,根据你的公共程序集调整
    private const string GlobalSharedResources = "/YourCommonAssembly;component/Resources/GlobalStyles.xaml";

    // 公共Shell:所有应用共用的主窗口(包含Prism区域)
    protected override Window CreateShell()
    {
        return Container.Resolve<MainShell>(); // MainShell放在公共程序集里
    }

    // 公共服务注册:所有应用都需要的服务
    protected virtual void RegisterSharedServices(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterSingleton<ICommonAuthService, CommonAuthService>();
        containerRegistry.RegisterSingleton<IRegionAdapterMappings, RegionAdapterMappings>();
        // 其他公共服务...
    }

    // 公共模块注册:所有应用都要加载的模块
    protected virtual void ConfigureSharedModules(IModuleCatalog moduleCatalog)
    {
        moduleCatalog.AddModule<CommonNavigationModule>();
        moduleCatalog.AddModule<CommonSettingsModule>();
        // 其他公共模块...
    }

    // 加载全局公共资源
    private void LoadSharedResources()
    {
        var sharedDict = new ResourceDictionary
        {
            Source = new Uri(GlobalSharedResources, UriKind.RelativeOrAbsolute)
        };
        Application.Current.Resources.MergedDictionaries.Add(sharedDict);
    }

    // 留给子类实现的抽象方法:注册当前应用特有的服务
    protected abstract void RegisterSpecificServices(IContainerRegistry containerRegistry);

    // 留给子类实现的抽象方法:配置当前应用特有的模块(负责不同区域的内容)
    protected abstract void ConfigureSpecificModules(IModuleCatalog moduleCatalog);

    // 重写Prism的注册逻辑:先公共,再特定
    sealed override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        RegisterSharedServices(containerRegistry);
        RegisterSpecificServices(containerRegistry);
    }

    // 重写Prism的模块配置:先公共,再特定
    sealed override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
    {
        ConfigureSharedModules(moduleCatalog);
        ConfigureSpecificModules(moduleCatalog);
    }

    // 初始化Shell后加载公共资源
    protected override void InitializeShell(Window shell)
    {
        base.InitializeShell(shell);
        LoadSharedResources();
    }
}

2. 实现具体应用的MySpecificApplication

具体应用只需要继承BaseApp,实现两个抽象方法,注册自己的专属服务和模块(这些模块就是负责加载不同Prism区域内容的核心):

using Prism.Ioc;
using Prism.Modularity;

public partial class MySpecificApplication : BaseApp
{
    // 注册当前应用特有的服务
    protected override void RegisterSpecificServices(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<ISpecificBusinessService, SpecificBusinessService>();
    }

    // 配置当前应用特有的模块:这些模块会向Prism区域注册各自的视图
    protected override void ConfigureSpecificModules(IModuleCatalog moduleCatalog)
    {
        moduleCatalog.AddModule<SalesDashboardModule>(); // 负责加载销售区域的内容
        moduleCatalog.AddModule<CustomerManagementModule>(); // 负责加载客户管理区域的内容
    }
}

3. 调整具体应用的App.xaml

WPF的App.xaml需要指向我们的MySpecificApplication,并且移除StartupUri(因为Prism会通过CreateShell自动加载主窗口):

<base:BaseApp x:Class="YourSpecificApp.MySpecificApplication"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:base="clr-namespace:YourCommonAssembly.AppCore;assembly=YourCommonAssembly">
    <!-- 这里可以添加当前应用特有的资源,会自动覆盖公共资源中的同名项 -->
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!-- 可选:添加当前应用专属的资源字典 -->
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</base:BaseApp>
关键注意事项
  • 公共程序集隔离:把BaseApp、MainShell、公共服务/模块都放在单独的类库中,所有具体应用引用这个类库即可。
  • 区域内容差异化:不同应用的区域内容完全通过各自的模块实现,模块内部使用IRegionManager向指定区域注册视图,完全不影响公共逻辑。
  • 资源优先级:具体应用的资源会覆盖公共资源中的同名资源,满足个性化需求的同时不破坏复用性。
  • Prism生命周期兼容:所有逻辑都遵循Prism的生命周期,不会出现初始化顺序问题,比如资源加载放在InitializeShell确保Shell已经初始化完成。

内容的提问来源于stack exchange,提问作者J4N

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:46:16