Простой Инжектор дает ошибку несоответствия образа жизни, в то время как оба класса зарегистрированы как синглтон - PullRequest
0 голосов
/ 25 октября 2018

Итак, у меня есть код подключения IoC Simple Injector

container.RegisterSingleton<IMsgProcessor, PrometheusTickerPublisher>();
container.RegisterSingleton<ICollector, UpdatesPerSecondDataCollector>();

И когда я пытаюсь запустить свое приложение, я получаю это сообщение об ошибке

Обнаружено несоответствие образа жизни,PrometheusTickerPublisher (Singleton) зависит от UpdatesPerSecondDataCollector (Transient).Несоответствие образа жизни может привести к ошибкам параллелизма в вашем приложении.Пожалуйста, посмотрите https://simpleinjector.org/dialm, чтобы понять эту проблему и как ее решить.

Я не понимаю этого вообще.Оба предмета зарегистрированы как синглтоны.Затем я изменил регистрацию на это, чтобы увидеть, могу ли я быть более явным в том, что это синглтон

container.RegisterSingleton<IMsgProcessor, PrometheusTickerPublisher>();
container.AddRegistration(typeof(ICollector), CreateCollectorRegistration(container));

internal static Registration CreateCollectorRegistration(Container container)
{
    return
        Lifestyle.Singleton.CreateRegistration<ICollector>(
            () =>
            {
                var timeProvider = container.GetInstance<ITimeProvider>();
                return new UpdatesPerSecondDataCollector(timeProvider);
            }, container);
}

Но это дает ту же ошибку

В этот момент я полностью потерян,Любые идеи

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Звонок Container.Verify() в конце процесса регистрации проверит состояние контейнера .Если вы сделаете это, это даст вам еще больше отзывов:

Конфигурация недействительна.Сообщалось о следующих диагностических предупреждениях:

- [Несоответствие образа жизни] PrometheusTickerPublisher (Singleton) зависит от UpdatesPerSecondDataCollector (Transient).

- [Зависимость из-за короткого замыкания] PrometheusTickerPublisher может неправильно зависеть от типаЗадать переменные (не зарегистрированы)Transient) вместо ICollector (Singleton).

- [Неоднозначные образы жизни] Регистрация для UpdatesPerSecondDataCollector (Transient) сопоставляется с той же реализацией (UpdatesPerSecondDataCollector), что и регистрация для ICollector (Singleton), но регистрация сопоставляется сдругой образ жизни.Это приведет к тому, что каждая регистрация будет преобразована в отдельный экземпляр.

- [Неоднозначные образы жизни] Регистрация для ICollector (Singleton) сопоставляется с той же реализацией (UpdatesPerSecondDataCollector), что и регистрация для UpdatesPerSecondDataCollector (Transient), норегистрация карт для другого образа жизни.Это приведет к тому, что каждая регистрация будет преобразована в другой экземпляр.См. Свойство Error для получения подробной информации о предупреждениях.

Пожалуйста, посмотрите https://simpleinjector.org/diagnostics, как исправить проблемы и как подавить отдельные предупреждения.

Самая интересная часть здесь Предупреждение о короткозамкнутой зависимости :

- [Зависимость при коротком замыкании] PrometheusTickerPublisher может некорректно зависеть от незарегистрированного типа UpdatesPerSecondDataCollector (переходный процесс) вместо ICollector (Singleton).

Другими словами, Simple Injector обнаруживает, что вы зарегистрировали UpdatesPerSecondDataCollector через ICollector как Singleton, но вы обходите эту ICollector регистрацию с помощьюв зависимости от реализации UpdatesPerSecondDataCollector.Это называется коротким замыканием, потому что вместо использования регистрации ICollector вы переходите непосредственно к (незарегистрированной) реализации.Это может вызвать всевозможные проблемы.

Поскольку явной регистрации для UpdatesPerSecondDataCollector нет, Simple Injector неявно зарегистрирует ее для вас и использует стиль жизни Transient (если не указано иное).Регистрация для ICollector, однако, является Singleton, так что это может вызвать проблемы.Это снова отмечено в предупреждении Неоднозначные образы жизни :

- [Неоднозначные образы жизни] Регистрация для UpdatesPerSecondDataCollector (Transient) соответствует той же реализации (UpdatesPerSecondDataCollector), что и регистрация для ICollector.(Singleton), но регистрация соответствует другому образу жизни.Это приведет к тому, что каждая регистрация будет разрешена в другой экземпляр.

Без вызова Verify все эти проблемы остаются незамеченными.Единственным подтверждением, которое выполняет Simple Injector при разрешении типа, является Несоответствие образа жизни , поэтому вы получили только следующую ошибку:

Обнаружено несоответствие образа жизни.PrometheusTickerPublisher (Singleton) зависит от UpdatesPerSecondDataCollector (Transient).

Короче говоря, вы не зарегистрировали UpdatesPerSecondDataCollector сами по себе, а только по его абстракции ICollector, в результате чего Simple инжектор неявно сделал Transient регистрацию для UpdatesPerSecondDataCollector на вашемот имени.Поскольку эта регистрация Transient, Simple Injector заблокировал ее внедрение в Singleton класс PrometheusTickerPublisher.Если бы вы позвонили Container.Verify(), было бы очень подробное описание проблемы, которая идет не так, что гораздо больше, чем простое несоответствие образа жизни.

0 голосов
/ 25 октября 2018

Хорошо, поэтому я выяснил, в чем проблема, мой класс ожидал точного типа UpdatesPerSecondDataCollector, а не ICollector, поэтому я предполагаю, что поскольку я не регистрировал тип явно, он каждый раз решался как переходныйSimpleInjector.Решение было просто сделать это при регистрации в МОК

container.RegisterSingleton<UpdatesPerSecondDataCollector>();

Это то, что ожидал мой нижестоящий класс

Дело закрыто

...