2016-06-21 4 views
0

У меня есть сценарий, где у меня есть два класса, давайте назовем их SingletonWorker и ScopedWorker, зарегистрированными в режиме Singleton и Scoped. Оба они зависят от IMetricSubmitter в своем конструкторе. Работники представляют показатели как часть своей логики, используя IMetricSubmitter. Там в одноэлементно реализации для IMetricSubmitter называется DefaultMetricSubmitter, который я хотел бы украсить EnrichMetricsDecorator с целью ScopedWorker зависимости, например, что SingletonWorker будет в конечном итоге с DefaultMetricSubmitter и ScopedWorker будет в конечном итоге с 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' украшает singleton 'DefaultMetricsSubmitter', я ошибаюсь? – Eldar

+0

Извините, я не читал это хорошо. Выглядит точно, что мне нужно, проверит. Спасибо :) – Eldar

+0

Привет, Стивен, ваше предложение сработало, но у меня есть немного более сложный граф объектов, где он терпит неудачу. Продолжая приведенный выше пример, 'DefaultMetricSubmitter' должен быть всегда украшен singleton' CachingMetricSubmitterDecorator', а 'CachingMetricSubmitterDecorator' должен быть украшен' EnrichMetricsDecorator' на основе условия, что у потребителя есть стиль «Scoped». Поэтому 'SingletonWorker' должен получить' CachingMetricSubmitterDecorator', украшающий 'DefaultMetricsSubmitter'. Как мне подойти к этому? – Eldar