2016-06-21 25 views
0

我有一个场景,我有两个班级,我们称之为SingletonWorkerScopedWorker,分别注册到Singleton和Scoped生活方式。两者在构造函数中都依赖于IMetricSubmitter。工作人员使用IMetricSubmitter作为其逻辑的一部分提交度量标准。有一个为IMetricSubmitter单身实现所谓DefaultMetricSubmitter,我喜欢与EnrichMetricsDecorator装饰为ScopedWorker依赖的目的,这样SingletonWorker将结束DefaultMetricSubmitterScopedWorker将结束EnrichMetricsDecorator装饰DefaultMetricSubmitter。有没有办法使用SimpleInjector创建这样的注册?如何根据消费者生活方式使用简单注射器有条件地注册装饰者?

的对象图应该基本上是这样的:

var singleton = new SingletonWorker(
    new DefaultMetricSubmitter()); 

var scoped = new ScopedWorker(
    new EnrichMetricsDecorator(
     new DefaultMetricSubmitter())); 

对我来说,它看起来像RegisterConditional,其中有知道该消费者的谓词,结合RegisterDecorator这是注册装饰的方式,但我不知道有什么方法可以将两者结合起来。理想情况下,我希望向装饰器注册一个条件,该条件基于是否存在一个活动范围,当它被请求作为消耗构造函数的依赖项时,并且在这种情况下为该活动范围创建装饰器实例。为了辩论的目的,范围可以被假定为LifetimeScope

回答

1

使用RegisterDecorator方法无法执行您想要的操作。相反,您将不得不恢复使用RegisterConditional方法。考虑到你的给予对象图,这些注册应该是这个样子:

container.Register<ScopedWorker>(Lifestyle.Scoped); 
container.Register<SingletonWorker>(Lifestyle.Singleton); 

container.RegisterConditional<IMetricSubmitter, EnrichMetricsDecorator>(
    Lifestyle.Scoped, 
    c => c.Consumer.ImplementationType == typeof(ScopedWorker)); 

container.RegisterConditional<IMetricSubmitter, DefaultMetricSubmitter>(
    Lifestyle.Singleton, 
    c => c.Consumer.ImplementationType == typeof(EnrichMetricsDecorator)); 

这种做法的文档中描述here

UPDATE

有了更新的对象图(包括额外的单装饰),注册可能如下所示:

// Useful helper method 
static bool InjectedInto<TConsumer>(PredicateContext c) => 
    c.Consumer.ImplementationType == typeof(TConsumer); 

container.Register<ScopedWorker>(Lifestyle.Scoped); 
container.Register<SingletonWorker>(Lifestyle.Singleton); 

container.RegisterConditional<IMetricSubmitter, DefaultMetricSubmitter>(
    Lifestyle.Singleton, 
    InjectedInto<CachingMetricSubmitterDecorator>); 

container.RegisterConditional<IMetricSubmitter, CachingMetricSubmitterDecorator>(
    Lifestyle.Singleton, 
    c=> !InjectedInto<ScopedWorker>(c)&&!InjectedInto<CachingMetricSubmitterDecorator>(c)); 

container.RegisterConditional<IMetricSubmitter, EnrichMetricsDecorator>(
    Lifestyle.Scoped, 
    InjectedInto<ScopedWorker>); 
+0

根据这个登记不会有文件' EnrichMetricsDecorator'装饰单身'DefaultMetricsSubmitter',我错了吗? – Eldar

+0

对不起,我没看完。看看我需要什么,会检查出来。谢谢:) – Eldar

+0

嗨史蒂文,你的建议工作,但我有一个更复杂的对象图失败。继续上面的例子,'DefaultMetricSubmitter'应该总是用单独的'CachingMetricSubmitterDecorator'装饰,'CachingMetricSubmitterDecorator'应该用'EnrichMetricsDecorator'装饰,这是基于消费者拥有'Scoped'生活方式的条件。所以'SingletonWorker'应该接收一个'CachingMetricSubmitterDecorator'来装饰'DefaultMetricsSubmitter'。我应该如何处理这个问题? – Eldar

相关问题