简体   繁体   English

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

[英]Registering same singleton for multiple interfaces in IOC

I have a service that needs to be able to handle native assets and attribute types, so I have a core service in my PCL called BaseThemeService which implements interface IThemeService . 我有一个需要能够处理本机资产和属性类型的服务,因此我的PCL中有一个名为BaseThemeService的核心服务,它实现了接口IThemeService I need to be able to access some attributes from the core PCL, which is why it implements the IThemeService from the core PCL. 我需要能够从核心PCL访问一些属性,这就是它从核心PCL实现IThemeService原因。

Within each platform project, I have a class ThemeService which implements IDroidThemeService and extends BaseThemeService . 在每个平台项目中,我有一个类ThemeService ,它实现了IDroidThemeService并扩展了BaseThemeService I then register the IDroidThemeService singleton in the setup of each project manually. 然后我手动在每个项目的设置中注册IDroidThemeService单例。

This works, except that there are now 2 instances of BaseThemeService . 这有效,但现在有2个BaseThemeService实例。 1 that is registered for the IThemeService for the core, and 1 that is registered for the IDroidThemeService for the platform. 1为核心的IThemeService注册,1为平台的IDroidThemeService注册。

To work around this I construct it myself and then register each appropriately: 为了解决这个问题,我自己构建它,然后适当地注册每个:

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

    base.InitializeFirstChance();
}

This seems like it should work, but it doesn't since the IMvxJsonConverter and IMvxResourceLoader services have not been registered yet. 这似乎应该可行,但它没有,因为IMvxJsonConverterIMvxResourceLoader服务尚未注册。

I see in the MvvmCross documentation that auto-loading using lazy construction will register a service with all implemented interfaces. 我在MvvmCross文档中看到,使用延迟构造的自动加载将注册所有已实现接口的服务。 Is there a way to use that functionality here to remove the manual registration? 有没有办法在这里使用该功能来删除手动注册?


Answer 回答

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;
}

This ended up being the ultimate resolution. 这最终成为最终解决方案。 I know the RegisterAsLazySingleton looks to solve this problem automatically, so I'll update again if I find a way to implement this that is slightly cleaner. 我知道RegisterAsLazySingleton会自动解决这个问题,所以如果我找到一种方法来实现这个问题,我会再次更新。

You can register a factory for the singleton which can produce a singleton manually and return that whenever anyone wants to call it. 您可以为单身人士注册工厂,该工厂可以手动生成单件,并在有人想要调用它时返回。 See the docs for Lazy Singleton Registration 请参阅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();
}

Depending on your situation, it may be appropriate for the field and method to be static. 根据您的具体情况,字段和方法可能是静态的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM