DryIOC在Facades之间共享单身人士

时间:2016-11-09 12:39:36

标签: dryioc

我正在开发一个系统,可以在几个不同的时间范围内处理各种金融工具的财务数据。

例如:

EUR/USD
  - m1 Timeframe (1 Minute)
  - m5 Timeframe (5 Minute)
  - m15 Timeframe (15 Minute)
GBP/USD
  - m1 Timeframe (1 Minute)
  - m5 Timeframe (5 Minute)
  - m15 Timeframe (15 Minute)

每个时间帧都有一个相当复杂的处理管道,我正在使用DryIOC通过管道路由数据,使用如下所述的EventAggregator:DryIOC Event Aggregator

DryIOC非常适合这种方式,因为它超快,可以跟上我需要的数据/事件量。

我有仪器级别的依赖关系,需要在该工具的不同时间范围之间共享。

我还有全局依赖项,例如代理连接管理器,需要在所有工具和所有时间帧之间共享。

容器是在运行时创建的;我可以打开/关闭不同的乐器和时间表,并且需要制作一个新的容器。

门面看起来很完美。我可以从一个全局容器开始,对于任何被激活的仪器,都可以为仪器制作Facade。然后从该容器中为每个时间帧创建一个容器。 Facade容器中的解析使用在那里定义的本地注册,然后在未解析时回退到父级。

但是,如文档中所述,Facades拥有自己的单身人士。当我尝试将Facade中的全局依赖关系解析为单例时,我得到一个新实例。

此测试失败:

[Test]
public void Test()
{
    var globalContainer = new Container();

    globalContainer.Register<IGlobalDependency, GlobalDependency>(Reuse.Singleton);

    var EURUSD_Container = new Container(rules => rules.WithFallbackContainer(globalContainer));

    EURUSD_Container.Register<IInstrumentDependency, InstrumentDependency>(Reuse.Singleton);

    var EURUSD_Timeframe_1_Container = EURUSD_Container.CreateFacade();

    EURUSD_Timeframe_1_Container.Register<ITimeframeDependency, TimeframeDependency>(Reuse.Singleton);

    var EURUSD_Timeframe_2_Container = EURUSD_Container.CreateFacade();
    EURUSD_Timeframe_2_Container.Register<ITimeframeDependency, TimeframeDependency>(Reuse.Singleton);


    var globalfromTimeframe1 = EURUSD_Timeframe_1_Container.Resolve<IGlobalDependency>();
    var globalfromTimeframe2 = EURUSD_Timeframe_2_Container.Resolve<IGlobalDependency>();

    Assert.AreSame(globalfromTimeframe1, globalfromTimeframe2);
}

我花了三天时间与Facades,Scopes,NamedScopes以及所有这些东西的组合作斗争。范围不起作用,因为如果我为一个工具创建一个新的范围,然后为该工具中的每个时间范围设置一个新范围并使用InCurrent范围解决 - 我仍然会得到一个新版本,因为每个时间范围都在其自己的范围内。

命名范围不起作用,因为我只知道运行时的仪器名称,并为新仪器添加新的注册,时间帧相互冲突。

如何将子容器分开,然后与父母分享单身人士?

更新

public void ScopeTest()
{
    var globalContainer = new Container();

    globalContainer.Register<IGlobalDependency, GlobalDependency>(Reuse.Singleton);

    var EURUSD_Container = globalContainer.OpenScope("EUR/USD");

    EURUSD_Container.Register<IInstrumentDependency, InstrumentDependency>(Reuse.InCurrentNamedScope("EUR/USD"), serviceKey: "EUR/USD");

    var EURUSD_Timeframe_1_Container = EURUSD_Container.OpenScope("m1");

    EURUSD_Timeframe_1_Container.Register<ITimeframeDependency, TimeframeDependency>(Reuse.InCurrentNamedScope("m1"), serviceKey: "m1");

    var EURUSD_Timeframe_2_Container = EURUSD_Timeframe_1_Container.OpenScope("m5");

    EURUSD_Timeframe_2_Container.Register<ITimeframeDependency, TimeframeDependency>(Reuse.InCurrentNamedScope("m5"), serviceKey:"m5");

    var USDJPY_Container = globalContainer.OpenScope("USD/JPY");

    EURUSD_Container.Register<IInstrumentDependency, InstrumentDependency>(Reuse.InCurrentNamedScope("USD/JPY"), serviceKey: "USD/JPY");

    var USDJPY_Timeframe_1_Container = USDJPY_Container.OpenScope("m1");

    USDJPY_Timeframe_1_Container.Register<ITimeframeDependency, TimeframeDependency>(Reuse.InCurrentNamedScope("m1"), serviceKey:"m1");

    var USDJPY_Timeframe_2_Container = USDJPY_Container.OpenScope("m5");

    USDJPY_Timeframe_2_Container.Register<ITimeframeDependency, TimeframeDependency>(Reuse.InCurrentNamedScope("m5"), serviceKey:"m5");

    var globalfromEURUSDTimeframe1 = EURUSD_Timeframe_1_Container.Resolve<IGlobalDependency>();
    var globalfromEURUSDTimeframe2 = EURUSD_Timeframe_2_Container.Resolve<IGlobalDependency>();

    var globalfromUSDJPYTimeframe1 = EURUSD_Timeframe_1_Container.Resolve<IGlobalDependency>();
    var globalfromUSDJPYTimeframe2 = EURUSD_Timeframe_2_Container.Resolve<IGlobalDependency>();

    Assert.AreSame(globalfromEURUSDTimeframe1, globalfromEURUSDTimeframe2);
    Assert.AreSame(globalfromUSDJPYTimeframe1, globalfromUSDJPYTimeframe2);
    Assert.AreSame(globalfromEURUSDTimeframe1, globalfromUSDJPYTimeframe2);
}

产生以下异常:

DryIoc.ContainerException: Unable to register service Namespace.ITimeframeDependency - {DI=25, ImplType="Namespace.TimeframeDependency", Reuse=CurrentScopeReuse {Name="m1", Lifespan=100}} with duplicate key [m1].  Already registered service with same key is {ID=22.... etc.... Name="m1" 

侧面说明它太烦人了,你无法从visual studio测试运行器中复制异常。

1 个答案:

答案 0 :(得分:2)

我最终通过使用WithRegistrationsCopy()

来实现这一目标

e.g。

_localContainer = container.WithRegistrationsCopy();

这允许我在子容器中获得顶级单例实例,但也在子容器中具有其他容器不知道的特定注册。