依赖注入:如何在其他项目的代码后置文件中访问服务?
解决WinUI模板项目中引用项目获取依赖注入服务的问题
方案1:创建全局可访问的服务提供者定位器
在主项目中新增一个静态类,用于存储并暴露ServiceProvider,让引用项目可以访问:
// 主项目中新增ServiceProviderLocator.cs public static class ServiceProviderLocator { public static IServiceProvider? Current { get; set; } }
接着在App.xaml.cs的服务初始化完成后,将主机的服务提供者赋值给这个定位器:
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { // 保留原有初始化代码 var host = Host; ServiceProviderLocator.Current = host.Services; // 其余启动逻辑... }
方案2:在引用项目的控件中获取ViewModel
在引用项目的控件里,通过ServiceProviderLocator获取对应ViewModel,可在控件Loaded事件中完成初始化:
// 引用项目的控件代码 public sealed partial class CustomControl : UserControl { public CustomViewModel ViewModel { get; } public CustomControl() { this.InitializeComponent(); this.Loaded += CustomControl_Loaded; } private void CustomControl_Loaded(object sender, RoutedEventArgs e) { // 从定位器获取ViewModel,兜底实例化避免空引用 ViewModel = ServiceProviderLocator.Current?.GetService<CustomViewModel>() ?? new CustomViewModel(); DataContext = ViewModel; } }
方案3:自定义XAML扩展简化绑定(可选)
如果想直接在XAML中绑定ViewModel,可以自定义一个MarkupExtension:
// 引用项目中新增ServiceProviderExtension.cs public class ServiceProviderExtension : MarkupExtension { public Type ServiceType { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { return ServiceProviderLocator.Current?.GetService(ServiceType) ?? Activator.CreateInstance(ServiceType); } }
然后在XAML中直接使用:
<UserControl x:Class="YourReferencedProject.CustomControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:YourReferencedProject" DataContext="{local:ServiceProviderExtension ServiceType={x:Type local:CustomViewModel}}"> <!-- 控件内容 --> </UserControl>
注意事项
- 若想更规范,可将
ServiceProviderLocator放在独立的共享类库中,让主项目和引用项目都引用该类库 - 务必处理
ServiceProviderLocator.Current为空的情况,避免运行时空引用异常
内容的提问来源于stack exchange,提问作者MarkusParker
相关产品推荐
相关产品推荐

