В данном случае пример стоит тысячи слов:
interface IProvider {
}
class DefaultProvider : IProvider {
private readonly ProviderSettings settings;
public DefaultProvider(ProviderSettings settings) {
this.settings = settings;
}
}
class ProviderSettings {
string Name { get; set;}
}
class SystemProviderSettings : ProviderSettings {
public SystemProviderSettings() {
this.Name = "System";
}
}
class ContextualProviderSettings : ProviderSettings {
// etc.
}
Каждая IProvider
реализация должна принимать зависимость ctor от ProviderSettings, поскольку именно это позволяет нам переключать поставщиков без внесения каких-либо изменений в наше приложение.
Мы подключаем по умолчанию ProviderSettings
, чтобы быть ContextualProviderSettings
. Как вы можете догадаться, этот набор Name
основан на чем-то контекстном, скажем, имени текущего пользователя.
Однако в некоторых случаях мы хотим использовать SystemProviderSettings
. Обычно это для конкретной услуги:
public class SomeSystemService : ISomeService {
public SomeSystemService(IProvider provider) {
// I need a provider scoped for the "system"
}
}
Затем мне нужно немного поработать, чтобы связать эти зависимости с моим инструментом DI (StructureMap):
For<ISomeService>().Use<SomeService>()
.Ctor<IStorageProvider>()
.Is(ctx => ctx.GetInstance<IStorageProvider>... this feels wrong
Так что я думаю, что это можно сделать лучше. Я пробовал шаблон декоратора, но я не хочу украшать конкретную реализацию IProvider
. Идея заключалась бы в том, чтобы иметь SystemProvider
, который упаковывает все, что было настроено как значение по умолчанию IProvider
.