ContainerLocator
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...
}
}