为 IOC 中的多个接口注册相同的单例

Registering same singleton for multiple interfaces in IOC

我有一项服务需要能够处理本机资产和属性类型,因此我的 PCL 中有一项名为 BaseThemeService 的核心服务,它实现了接口 IThemeService。我需要能够从核心 PCL 访问一些属性,这就是它从核心 PCL.

实现 IThemeService 的原因

在每个平台项目中,我都有一个 class ThemeService 实现 IDroidThemeService 并扩展 BaseThemeService。然后我在每个项目的设置中手动注册 IDroidThemeService 单例。

这有效,除了现在有 2 个 BaseThemeService 实例。 1 个为核心 IThemeService 注册,1 个为平台 IDroidThemeService 注册。

为了解决这个问题,我自己构建了它,然后适当地注册了每一个:

protected override void InitializeFirstChance()
{
    ThemeService themeService = new ThemeService(Mvx.Resolve<IMvxJsonConverter>(), Mvx.Resolve<IMvxResourceLoader>());
    Mvx.RegisterSingleton<IDroidThemeService>(themeService);
    Mvx.RegisterSingleton<IThemeService>(themeService);

    base.InitializeFirstChance();
}

这似乎应该有效,但由于 IMvxJsonConverterIMvxResourceLoader 服务尚未注册,因此无效。

我在 MvvmCross 文档中看到使用惰性构造的自动加载将使用所有已实现的接口注册服务。有没有办法在这里使用该功能来删除手动注册?


回答

protected override void InitializeFirstChance()
{
    Mvx.RegisterSingleton<IDroidThemeService>(GetThemeService);
    Mvx.RegisterSingleton<IThemeService>(GetThemeService);

    base.InitializeFirstChance();
}

private DroidThemeService DroidSingletonService = null;
private DroidThemeService GetThemeService()
{
    if (DroidSingletonService == null)
    {
        DroidSingletonService = Mvx.IocConstruct<DroidThemeService>();
    }
    return DroidSingletonService;
}

这是最终的解决方案。我知道 RegisterAsLazySingleton 看起来可以自动解决这个问题,所以如果我找到一种更简洁的实现方法,我会再次更新。

您可以为单例注册一个可以手动生成单例的工厂,并且 return 任何人都想调用它。 See the docs for Lazy Singleton Registration

ThemeService singletonService = null;
private ThemeService GetThemeService() 
{
    if (singletonService == null) 
    {
        singletonService = new ThemeService(Mvx.Resolve<IMvxJsonConverter>(), Mvx.Resolve<IMvxResourceLoader>());
    }
    return singletonService;
}

protected override void InitializeFirstChance()
{
    Mvx.RegisterSingleton<IDroidThemeService>(GetThemeService);
    Mvx.RegisterSingleton<IThemeService>(GetThemeService);

    base.InitializeFirstChance();
}

根据您的情况,字段和方法可能是静态的。