В последнее время я много читал о шаблонах проектирования приложений: о DI, антипаттернах SL, AOP и многом другом. Причина в том, что я хочу прийти к компромиссу в дизайне: слабо связанный, чистый и простой в работе. DI кажется ПОЧТИ как решение, за исключением одной проблемы: сквозных и необязательных зависимостей, ведущих к загрязнению конструктора или свойства. Итак, у меня есть собственное решение этой проблемы, и я хочу знать, что вы о нем думаете.
Марк Симанн (автор книги DI и известного заявления «SL - это анти-шаблон») в своей книге упоминает паттерн, называемый «Окружающий контекст». Хотя он говорит, что ему это не очень нравится, этот шаблон по-прежнему интересен: он похож на старый добрый синглтон, за исключением того, что он ограничен и предоставляет значение по умолчанию, поэтому нам не нужно проверять значение null. У него есть один недостаток - его нет и он не может знать о своей сфере действия и о том, как избавиться от него.
Итак, почему бы не применить здесь Service Locator? Он может решить проблему как определения объема, так и удаления объектов окружающего контекста. Прежде чем вы скажете, что это антипаттерн: это когда вы скрываете контракт. Но в нашем случае мы скрываем ДОПОЛНИТЕЛЬНЫЙ контракт, так что это не так уж и плохо, ИМО.
Вот код, чтобы показать, что я имею в виду:
public interface ILogger
{
void Log(String text);
}
public interface ISomeRepository
{
// skipped
}
public class NullLogger : ILogger
{
#region ILogger Members
public void Log(string text)
{
// do nothing
}
#endregion
}
public class LoggerContext
{
public static ILogger Current
{
get
{
if(ServiceLocator.Current == null)
{
return new NullLogger();
}
var instance = ServiceLocator.Current.GetInstance<ILogger>();
if (instance == null)
{
instance = new NullLogger();
}
return instance;
}
}
}
public class SomeService(ISomeRepository repository)
{
public void DoSomething()
{
LoggerContext.Current.Log("Log something");
}
}
Изменить: я понимаю, что задание не конкретного вопроса противоречит дизайну переполнения стека. Поэтому я отмечу как ответ сообщение, которое лучше всего описывает, почему этот дизайн плохой ИЛИ лучше дает лучшее решение (или, может быть, дополнение?). Но не предлагайте АОП, это хорошо, но это не решение, когда вы действительно хотите что-то сделать внутри своего кода.
Изменить 2: я добавил проверку для ServiceLocator.Current имеет значение null. Это то, что я намереваюсь сделать в своем коде: работать с настройками по умолчанию, когда SL не настроен.
LoggerContext.Current
вместо того, чтобы вводитьILogger
в свой код. По моему опыту, если вам нужно внедрить многоILogger
зависимостей в ваш код, вы либо слишком много ведете журнал (вместо того, чтобы генерировать исключения), либо не соблюдаете SRP (и вам действительно нужен AOP). Взгляните на этот ответ: stackoverflow.com/questions/9892137/. - person Steven   schedule 21.05.2012