csharpshare.com
Show / Hide Table of Contents

ContainerLocator

Gitee仓库 Prism-Documentation-CH 时间 2023-1-13

ContainerLocator是Prism 8.0中的新功能。为了帮助Prism摆脱对CommonServiceLocator的依赖,并解决一些我们必须回退到ServiceLocator模式的内部问题(如XAML扩展)。

ContainerLocator还为Prism带来了一些额外的好处,特别是对于那些从事跨平台应用程序(如Xamarin.Forms或Uno Platform)的开发人员而言。在这种情况下,有时可能需要在初始化PrismApplication之前就初始化容器。一个较为常见的例子是使用了Shiny的应用程序。对于此类应用程序,您可能希望将ServiceCollection添加到您的Prism容器中,然后把ServiceProvider返回给Shiny。这将允许Prism和Shiny都维护一个容器而不是多个容器。

[!注意] 对于那些赞助了Dan Siegel 的开发者,建议你使用Prism.Magician。

如何使用ContainerLocator

请注意,ContainerLocator可以通过委托的方式来创建容器以实现容器实例的懒加载。在ContainerLocator.Container被调用之前,它并不会创建容器。

var createContainerExtension = () => new DryIocContainerExtension();
ContainerLocator.SetContainerExtension(createContainerExtension);

[!警告] 如果您在设置创建的委托后并未调用ContainerLocator.Current或ContainerLocator.Container,则对SetContainerExtension的后续调用将覆盖您的初始委托。

高级用法

请注意,此处的信息仅适用于高级开发人员。这些API在IDE的智能感知中被有意隐藏起来,因为它们并不适用于普通开发者。使用它们需要您自担风险,并且只能在适当的情况下使用。

当您需要访问原始的IContainerExtension时,可以通过访问ContainerLocator.Current来实现。

测试

虽然并非完全不常见的问题,但在进行单元测试时,通常建议您重置ContainerLocator。这会确保容器被释放,并且容器实例与委托一起被清除以便创建新的实例。

public class SomeTests : IDisposible
{
    public void Dispose()
    {
        ContainerLocator.ResetContainer();
    }
}

用法示例

在ShinyStartup中,你可能会有以下内容:

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();
    }
}

在XAML扩展中

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...
    }
}
本文导航
返回顶部 ©2022-2023 csharpshare.com    冀ICP备2022026743号-1     公安备案图标 冀公网安备 13052902000206号     Icons by Icons8