根据结构图中的参数解析具体类型



我正在尝试解决依赖于我正在调用的操作中的参数值的依赖关系。

我有这个 WCF 服务

public class InformationService : IInformationService
{
    private readonly IValueProvider _valueProvider;
    public InformationService(IValueProvider valueProvider)
    {
        _valueProvider= valueProvider;
    }

    public CompanyReportResponse CompanyReport(string option)
    {
        _valueProvider.Execute(option);
    }
}

我还在我的容器中为我的价值提供者注册了两种具体类型。

Registry.For<IValueProvider>().Add<ValueProvider1>().Named("No1");
Registry.For<IValueProvider>().Add<ValueProvider2>().Named("No2");

是否可以根据选项的值以某种方式使用不同的值提供程序?

即,当选项"value1"时,_valueProvider将使用具体类型ValueProvider1,当选项"value2"时,_valueProvider将使用具体类型ValueProvider2

+1 表示@filpen的答案。我喜欢添加第三个选项。您可以引入委托给正确实现的代理,而不是注入工厂或执行基于上下文的注入:

public SwitchingValueProviderProxy: IValueProvider
{
    private readonly ValueProvider1 provider1;
    private readonly ValueProvider2 provider2;
    public SwitchingValueProviderProxy(
        ValueProvider1 provider1,
        ValueProvider2 provider2)
    {
        this.provider1 = provider1;
        this.provider2 = provider2;
    }
    void IValueProvider.Execute(option option)
    {
        this.GetProvider(option).Execute(option);
    }
    private IValueProvider GetProvider(string option)
    {
        // custom instance logic here
        if (option.EndsWith("1"))
            return this.provider1;
        if (option.EndsWith("2"))
            return this.provider2;
        throw InvalidOperationException();
    }
}

这有几个明显的优势。首先,这完全隐藏了工厂和确定从客户端执行哪个提供程序的逻辑。客户端现在仅依赖于IValueProvider接口。接下来,配置现在变得非常干净:

Registry.For<IValueProvider>()
    .Add<SwitchingValueProviderProxy>();

就是这样。如果你这样做,你仍然可以将选择逻辑提取到IValueProviderFactory中并将其注入到SwitchingValueProviderProxy中,这使这个类保持简单和集中,并且仍然使应用程序的其余部分对工厂一无所知。

我看到至少 2 个不同的选项。

如果该方法仅使用ValueProvider,则可以考虑方法注入。由于在传递option参数的那一刻,您已经知道将使用哪一个参数,因此您可以为 IValueProvider 提供实现以用作附加参数。

public CompanyReportResponse CompanyReport(string option, IValueProvider provider)
{
    _provider.Execute(option);
}

第二个选项是定义一个工厂来构建你的 ValueProvider,并通过构造函数注入注入这个工厂。工厂将有一个方法,用于根据option参数实例化正确的 ValueProvider。

public interface IValueProviderFactory
{
    IValueProvider CreateProvider(string option);
}
public class ValueProviderFactory : IValueProviderFactory
{
    public IValueProvider CreateProvider(string option)
    {
         // Insert custom instantiation logic here:
         // if option == "value1" return ValueProvider1 and so on
    }
}
public class InformationService : IInformationService
{
    private readonly IValueProviderFactory _valueProviderFactory;
    public InformationService(IValueProviderFactory valueProviderFactory)
    {
        _valueProviderFactory = valueProviderFactory;
    }
    public CompanyReportResponse CompanyReport(string option)
    {
        var valueProvider = _valueProviderFactory.CreateProvider(option);
        valueProvider.Execute(option);
    }
}

最新更新