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

时间:2015-03-02 20:04:10

标签: c# xamarin mvvmcross

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

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

这是有效的,但现在有BaseThemeService的2个实例。 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看起来会自动解决这个问题,所以如果我找到一种方法来实现这个问题,我会再次更新。

1 个答案:

答案 0 :(得分:5)

您可以为单身人士注册工厂,该工厂可以手动生成单身人士,并在有人想要召唤时返回。 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();
}

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