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

Bay*_*que 6 c# mvvmcross xamarin

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

在每个平台项目中,我都有一个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();
}
Run Code Online (Sandbox Code Playgroud)

这似乎应该可行,但它并没有,因为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;
}
Run Code Online (Sandbox Code Playgroud)

这最终成为最终解决方案.我知道RegisterAsLazySingleton自动解决这个问题的外观,所以如果我找到一种方法来实现这个稍微清洁的话,我会再次更新.

Ste*_*ham 5

您可以为单身人士注册工厂,该工厂可以手动生成单件,并在有人想要调用它时返回.请参阅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();
}
Run Code Online (Sandbox Code Playgroud)

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

  • 似乎自动生成工具不直接支持用于针对多个接口注册单个实例的API.虽然看起来像拉动请求的好项目. (3认同)
  • 顺便说一句:您可以使用Mvx.IoCConstruct <ThemeService>().这将调用构造函数并自动解析参数,而不是为每个参数手动调用Resolve <T>(). (2认同)