如何在UWP应用中结合Autofac实现外观模式与依赖注入?
刚好做过类似的实现,给你梳理下在UWP里用Autofac结合外观模式的完整流程,完全匹配你提到的场景:
整体架构思路
我们用IFacade作为视图模型(VM)和后端业务模块的中间层,VM只依赖IFacade接口,不用关心后端具体的业务实现;Autofac负责在App启动时完成所有依赖的注册和解析,把IFacade的实例注入到VM中。
1. 定义IFacade外观接口
这个接口是VM和后端的“沟通桥梁”,所有VM需要的业务操作都在这里定义,内部负责转发到对应的后端模块:
public interface IFacade { // 示例方法:根据你的实际业务需求添加 Task<UserInfo> GetCurrentUserAsync(); Task SaveAppSettingsAsync(AppSettings settings); Task<List<Notification>> GetRecentNotificationsAsync(); }
2. 实现IFacade具体类
创建DefaultFacade(或者你喜欢的名称),通过构造函数注入后端的业务服务,然后实现接口方法,把VM的调用转发给对应的服务:
public class DefaultFacade : IFacade { private readonly IUserService _userService; private readonly ISettingsService _settingsService; private readonly INotificationService _notificationService; // 构造注入后端业务服务,解耦Facade和具体服务实现 public DefaultFacade(IUserService userService, ISettingsService settingsService, INotificationService notificationService) { _userService = userService; _settingsService = settingsService; _notificationService = notificationService; } public Task<UserInfo> GetCurrentUserAsync() { // 转发到用户服务 return _userService.GetCurrentUserAsync(); } public Task SaveAppSettingsAsync(AppSettings settings) { // 转发到设置服务 return _settingsService.SaveSettingsAsync(settings); } public Task<List<Notification>> GetRecentNotificationsAsync() { // 转发到通知服务 return _notificationService.GetRecentNotificationsAsync(); } }
3. 在App类中用Autofac配置依赖注入
在App的启动流程里,我们通过Autofac注册所有依赖(Facade、后端服务、VM等),然后解析出IFacade的实例,供整个应用使用:
public class App : Application { // 静态属性方便全局访问(或者你也可以通过DI注入到需要的地方) public static IFacade GlobalFacade { get; private set; } protected override void OnLaunched(LaunchActivatedEventArgs e) { // 先初始化依赖注入 GlobalFacade = InitializeDependencies(); // 常规UWP启动逻辑 Frame rootFrame = Window.Current.Content as Frame; if (rootFrame == null) { rootFrame = new Frame(); Window.Current.Content = rootFrame; } if (rootFrame.Content == null) { // 如果VM用构造注入,这里可以通过Autofac解析VM再传递,或者用MVVM框架的导航 rootFrame.Navigate(typeof(MainPage), e.Arguments); } Window.Current.Activate(); } private IFacade InitializeDependencies() { var containerBuilder = new ContainerBuilder(); // 注册Facade接口和实现,用SingleInstance保证全局唯一实例 containerBuilder.RegisterType<DefaultFacade>().As<IFacade>().SingleInstance(); // 注册后端业务服务,根据服务特性选择生命周期(比如SingleInstance、InstancePerDependency等) containerBuilder.RegisterType<UserService>().As<IUserService>().SingleInstance(); containerBuilder.RegisterType<SettingsService>().As<ISettingsService>().SingleInstance(); containerBuilder.RegisterType<NotificationService>().As<INotificationService>().SingleInstance(); // 注册视图模型,这里用InstancePerDependency表示每次请求都创建新实例 containerBuilder.RegisterType<MainViewModel>().InstancePerDependency(); // 构建容器并解析IFacade实例 var container = containerBuilder.Build(); return container.Resolve<IFacade>(); } }
4. 视图模型中使用IFacade
VM可以通过构造函数注入IFacade(推荐,符合依赖注入原则),或者直接访问App的静态属性,然后调用Facade的方法完成业务操作:
public class MainViewModel : ViewModelBase // 假设你用了MVVM Light或其他框架的ViewModel基类 { private readonly IFacade _facade; private UserInfo _currentUser; private bool _isLoading; public UserInfo CurrentUser { get => _currentUser; set => SetProperty(ref _currentUser, value); } public bool IsLoading { get => _isLoading; set => SetProperty(ref _isLoading, value); } public ICommand LoadCurrentUserCommand { get; } // 构造注入IFacade,由Autofac自动填充依赖 public MainViewModel(IFacade facade) { _facade = facade; LoadCurrentUserCommand = new RelayCommand(async () => await LoadCurrentUserAsync()); } private async Task LoadCurrentUserAsync() { IsLoading = true; try { CurrentUser = await _facade.GetCurrentUserAsync(); } catch (Exception ex) { // 处理异常,比如显示提示 Debug.WriteLine($"加载用户信息失败:{ex.Message}"); } finally { IsLoading = false; } } }
几个注意点
- 确保你已经安装了Autofac的NuGet包:直接搜索
Autofac安装核心包即可,UWP环境下不需要额外的扩展包 - 如果使用Prism等MVVM框架,可以结合Prism的Autofac集成模块,更方便地管理导航和VM的注入
- 生命周期选择:
SingleInstance适合无状态的全局服务,InstancePerDependency适合每次需要新实例的场景(比如VM) - 尽量避免直接访问
App.GlobalFacade,优先用构造注入,这样代码更易测试和维护
内容的提问来源于stack exchange,提问作者Kzryzstof
相关产品推荐
相关产品推荐

