在这种情况下,一个例子胜过千言万语:
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
实现都应该依赖于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
的内容。
答案 0 :(得分:0)
惊人的夜晚会睡觉。
简单的解决方案,使用工厂:
public class IProviderFactory {
IProvider Create(ProviderSettings settings);
}
我可以为每个提供程序实现创建一个工厂,并在运行时传入相关的ProviderSettings。