【WPF】Prism学习(九)

Prism Dependency Injection

1.Container Locator

1.1. Container Locator的引入

  • Container Locator是在Prism 8.0版本中新引入的一个特性。
  • 它的目的是为了帮助Prism框架摆脱对CommonServiceLocator的依赖,并解决一些必须回退到ServiceLocator模式的内部问题,比如在XAML扩展中。

1.2. ContainerLocator的好处

  • ContainerLocator对于使用Prism框架的开发者来说,尤其是那些开发跨平台应用(如Xamarin.Forms或Uno Platform)的开发者,提供了额外的好处。
  • 在某些情况下,开发者可能需要在初始化PrismApplication之前先初始化容器。一个常见的例子是使用Shiny框架的应用。在这种情况下,开发者可能希望将ServiceCollection添加到Prism容器中,然后将ServiceProvider返回给Shiny。这样,Prism和Shiny可以共同维护一个单一的容器,而不是拥有多个容器。

1.3. 对赞助Dan Siegel的开发者的特别说明

  • 对于那些赞助Dan Siegel的开发者,推荐使用Prism.Magician这个工具来实现上述功能。

2.如何使用Container Locator

2.1. 如何使用ContainerLocator

  • ContainerLocator可以通过一个委托(delegate)来延迟设置容器实例。这意味着,直到调用ContainerLocator.Container之前,容器不会被创建。

2.2. 示例代码

csharp 复制代码
var createContainerExtension = () => new DryIocContainerExtension();
ContainerLocator.SetContainerExtension(createContainerExtension);
  • 首先,定义一个委托createContainerExtension,当调用时会创建一个新的DryIocContainerExtension实例。
  • 然后,使用ContainerLocator.SetContainerExtension方法来设置这个委托。

2.3. 警告

  • 如果在设置创建委托之后,你没有调用ContainerLocator.CurrentContainerLocator.Container,那么后续对SetContainerExtension的调用将会覆盖你最初设置的委托。

强调了ContainerLocator的延迟创建特性,以及如何通过委托来设置容器实例。同时,提醒开发者在设置委托后需要调用相关方法,否则之前设置的委托可能会被新的调用覆盖。这是在使用ContainerLocator时需要注意的一个关键点。

3.高级用法

3.1. 高级用法:

  • 这部分内容仅适用于高级用户。这些API故意在智能感知( intellisense )中隐藏,因为它们不适用于普通用户。使用这些API时需要谨慎,并且只在正确的情境下使用。
  • 如果需要访问原始的IContainerExtension,可以通过访问ContainerLocator.Current来实现。

3.2. 测试:

  • 在单元测试中,通常建议重置ContainerLocator。这样可以确保容器被释放,容器实例和创建容器的委托都被清除,从而可以创建一个新的实例。
  • 给出了一个示例代码,展示了如何在测试类中实现IDisposable接口,并在Dispose方法中调用ContainerLocator.ResetContainer()来重置ContainerLocator。
csharp 复制代码
public class SomeTests : IDisposable
{
    public void Dispose()
    {
        ContainerLocator.ResetContainer();
    }
}

在使用高级API时需要谨慎,并在单元测试中重置ContainerLocator以确保容器被正确释放和清理。这对于确保测试的准确性和可靠性非常重要。

4.用法示例

4.1在ShinyStartup中

csharp 复制代码
public class MyStartup : ShinyStartup
{
    private void RegisterTypes(IContainerRegistry container)
    {
        // Your normal registrations here...
    }

    private IContainerExtension CreateContainerExtension() =>
        new DryIocContainerExtension();

    public override IServiceProvider CreateServiceProvider(IServiceCollection services)
    {
        ContainerLocator.SetContainerExtension(CreateContainerExtension);
        var container = ContainerLocator.Container;
        container.RegisterServices(services);
        RegisterTypes(container);
        return container.GetContainer();
    }
}

4.2在XAML扩展中

csharp 复制代码
public class SomeMarkupExtension : IMarkupExtension
{
    private static readonly Lazy<IEventAggregator> _lazyEventAggregator =
        new Lazy<IEventAggregator>(() => ContainerLocator.Container.Resolve<IEventAggregator>());

    private IEventAggregator EventAggregator => _lazyEventAggregator.Value;

    public object ProvideValue(IServiceProvider provider)
    {
        // your logic here...
    }
}

相关链接

相关推荐
茯苓gao13 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾14 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
DKPT14 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习
aaaweiaaaaaa14 小时前
HTML和CSS学习
前端·css·学习·html
看海天一色听风起雨落15 小时前
Python学习之装饰器
开发语言·python·学习
speop16 小时前
llm的一点学习笔记
笔记·学习
非凡ghost17 小时前
FxSound:提升音频体验,让音乐更动听
前端·学习·音视频·生活·软件需求
ue星空17 小时前
月2期学习笔记
学习·游戏·ue5
萧邀人17 小时前
第二课、熟悉Cocos Creator 编辑器界面
学习
m0_5713728218 小时前
嵌入式ARM架构学习2——汇编
arm开发·学习