csharpshare.com
Show / Hide Table of Contents

在Prism中注册类型

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

对于那些熟悉ASP.NET Core的人,你可能熟悉三种基本的依赖注册类型:瞬态(transient)、单例(singleton)和作用域(Scoped Services)。此处重要的是要去理解,为什么Prism对作用域既没有使用也没有实现。与web环境不同,在web环境中你的许多服务都是围绕用户请求进行的,而对于桌面和移动应用程序,我们只处理一个用户。因此对于内存管理和其他业务需求,我们必须决定我们的服务是否最适合作为在整个应用程序中重复使用的单个实例,还是在每次请求时创建一个新实例,并允许垃圾回收器在处理完内存后释放内存。

同样重要的是要考虑Prism对命名服务注册的使用有硬性要求。这将允许Prism注册您的页面并进行导航,然后基于像MyMasterDetailPage/NavigationPage/ViewA这样的Uri段来解析它。因此,任何不支持开箱即用命名服务的依赖注入容器都不能也不会由Prism团队正式实现。

注册瞬态服务(Transient Services)

对于那些你希望每次创建一个新实例的服务,你只需要调用Register方法,并提供服务类型和实现类型,除非在某些情况下,可能只需要简单地注册具体类型。

// 在FooService适合作为具体类型时使用
containerRegistry.Register<FooService>();

containerRegistry.Register<IBarService, BarService>();

注册单例服务(Singleton Services)

很多时候,您可能会在整个应用程序中使用一项服务。 因此每次需要服务时都创建一个新实例并不是一个好主意。 所以为了提供更好的内存管理,更好的做法是使此类服务成为可在整个应用程序中使用的单例。还有很多时候,您可能需要一种在应用程序的整个生命周期中保持其状态的服务。对于这两种情况中的任何一种,将您的服务注册为单例都更有意义。

[!注意] 单例服务在您的应用程序第一次解析服务之前,实际上并没有被创建也不会使用内存。

// 在FooService适合作为具体类型时使用
containerRegistry.RegisterSingleton<FooService>();

containerRegistry.RegisterSingleton<IBarService, BarService>();

注册实例服务

虽然很多时候你只想通过提供服务和实现类型来注册单例,但也有一些时候你可能想要新建一个服务实例并提供给给定的服务,或者你可能想要从MonkeyCache之类的插件注册当前实例,如下所示:

containerRegistry.RegisterInstance<IFoo>(new FooImplementation());

// 使用James Montemagno's Monkey Cache的例子
Barrel.ApplicationId = "your_unique_name_here";
containerRegistry.RegisterInstance<IBarrel>(Barrel.Current);

检查服务是否已注册

很多时候,特别是在编写Prism模块或插件时,您可能想检查服务是否已注册,然后根据它是否已注册来执行某些操作。

[!注意] 使用Prism模块时,如果您对给定服务有严格的依赖,则应将其注入到构造函数中,以便在缺少服务类型初始化模块时生成异常。如果您打算注册一个默认实现,您应该只使用IsRegistered来检查它。

if (containerRegistry.IsRegistered<ISomeService>())
{
    // Do something...
}

懒加载解决方案

如前所示,您可以像containerRegistry.Register<IFoo, Foo>()一样注册您的服务。许多开发人员可能希望使用Func<IFoo>或Lazy<IFoo>的形式节省内存和延迟加载服务。Prism 8对此开箱即用。为此您只需将参数添加到您的ViewModel或服务中,如下所示。

public class ViewAViewModel
{
    public ViewAViewModel(Func<IFoo> fooFactory, Lazy<IBar> lazyBar)
    {
    }
}

[!注意] 注意服务注册类型。当您使用单例服务时,使用Lazy<T>或Func<T>解决方案通常没有意义。例如IEventAggregator是一个单例,这意味着您将在整个应用程序中使用单个事件聚合器的实例。通过使用Lazy<T>或Func<T>,您最终会使用更多内存并且可能会影响性能,而不仅仅是直接请求服务。

解决所有的注册事项

一些开发人员可能会发现需要注册同一个服务的多个实现,并期望解决所有这些问题。作为一个常见的用例,Shiny将这种模式与它的一些委托接口一起使用。这可以让您通过以块状方式响应同一事件来构建更多模块化代码。同样,您不需要对注册做任何特别的事情。要使用此功能,您只需将IEnumerable<T>注入到您的构造函数中,如此处所示。

public class SomeService
{
    public SomeService(IEnumerable<IFoo> fooCollection)
    {
    }
}

[!注意] 此功能目前仅在DryIoc中受支持。当版本6发布时,此功能可能会对使用Unity Container的用户可用。

本文导航
返回顶部 ©2022-2023 csharpshare.com    冀ICP备2022026743号-1     公安备案图标 冀公网安备 13052902000206号     Icons by Icons8