Я работаю над большим унаследованным приложением C#, и задача, назначенная мне, заключается в том, чтобы удалить все применения статического заводского класса ServiceLocator.GetObject<T>()
и заменить на все вложенные зависимости конструктора.Требовать фабричный класс в методе расширения
По большей части это просто, однако в кодовой базе приложений есть около 50 случаев, где это немного сложно. Например, Servicelocator
используется в статическом классе или методе расширения или даже в WPF MarkupExtension !.
Например, если бы вы столкнулись с фрагментом кода, как это, что бы вы сделали? (Кроме крика)
public static class MyExtensions
{
private static ISingletonServiceOne _ServiceOne = null;
private static ISingletonServiceTwo _ServiceTwo = null; // etc ...
public static SummaryHeader GetBannerSummary(this IModel rfq, object requester)
{
Guard.ArgumentNotNull(rfq, "rfq");
Guard.ArgumentNotNull(requester, "requester");
if (_ServiceOne == null)
{
_ServiceOne = ServiceLocator.GetService<ISingletonServiceOne>(requester);
Guard.ArgumentNotNull(_ServiceOne, "_ServiceOne");
}
return _ServiceOne.GetBannerSummary(rfq);
}
В приведенных выше методе ServiceLocator.GetObject() используется в качестве метода расширения на IModel, чтобы найти одноплодный зарегистрированный сервис и выполнить метод на этом, используя IModel.
Возникает вопрос:
- Существуют ли какие-либо шаблоны/практики, чтобы избежать такого рода вещи - в DI контейнер, необходимый в статическом классе, стоимость преобразователя или метод расширения
- Существуют ли какие-либо шаблоны/методы решения циклических зависимостей в DI?
- Что бы вы сделали в вышеупомянутом задании, существует компромисс между хорошим кодом и временем доставки?
Я имею в виду, чтобы переместить GetBannerSummary() метод из расширений и только IModel в этом случае, однако (не смейтесь) бывают случаи одного и того же ServiceLocator используется в ValueConverters (WPF) и MarkupExtensions : 0
ваших комментариев/предложения оценило
Привет, спасибо за ответ - я отредактировал Requestor, поскольку внутренне реализация ServiceLocator на самом деле ничего не делает с ним! Согласитесь с вашим прогнозом. Это довольно шокирующая паутина спагетти, с которой я имею дело, поэтому любые предложения по ее расторжению приветствуются:) –
Привет, Андрей, приветствую - нам все пришлось пройти через это! Я думаю, что вы все делаете правильно, но я не вижу пути вокруг ServiceLocator в статике, расширениях и т. Д.Это необходимое зло, если вы сохранили все свои зависимости модульным, как и следовало ожидать. –
Да, большой рефакторинг, как требование, потребовало повторного использования большого фрагмента кода в качестве призмы «Модуль» в другом проекте. Моя реакция, когда я услышал, что это «LOL». Во всяком случае, из 120 применений ServiceLocator у меня сократилось до 60. Я думаю, что я смогу больше обрезать, но некоторые могут остаться, если нет «простого решения». Большое спасибо –