You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#双Web引用切换难题:基于Autofac实现生产/测试SOAP服务动态切换

解决方案:基于Autofac实现不同命名空间SOAP服务的动态切换

遇到这种不同命名空间、无统一接口的SOAP服务切换问题,最稳妥的方案是适配器模式+Autofac条件注册,既保留所有服务方法的可用性,又能轻松基于配置切换实现。下面是具体步骤:

步骤1:定义统一接口

先把两个服务的公共方法抽成一个统一接口,上层代码只依赖这个接口,完全隔离具体服务的差异。比如假设两个服务都有SubmitOrder和GetOrderStatus方法:

public interface ITradePortalService
{
    string SubmitOrder(OrderRequest request);
    OrderStatus GetOrderStatus(string orderId);
    // 这里添加所有你需要调用的公共方法
}

步骤2:为每个SOAP服务创建适配器

分别给两个命名空间的webServices类写适配器,实现上面的统一接口,内部直接调用对应服务的方法:

生产服务适配器

假设生产服务的命名空间是YourNamespace.ProductionService:

public class ProductionTradePortalAdapter : ITradePortalService
{
    private readonly YourNamespace.ProductionService.webServices _innerService;

    public ProductionTradePortalAdapter()
    {
        _innerService = new YourNamespace.ProductionService.webServices();
        // 这里可以根据需要设置服务地址、超时等参数
    }

    public string SubmitOrder(OrderRequest request)
    {
        // 若两个服务参数类不同,可在此做类型转换适配
        return _innerService.SubmitOrder(request);
    }

    public OrderStatus GetOrderStatus(string orderId)
    {
        return _innerService.GetOrderStatus(orderId);
    }
}

测试服务适配器

测试服务的命名空间是YourNamespace.TestService:

public class TestTradePortalAdapter : ITradePortalService
{
    private readonly YourNamespace.TestService.webServices _innerService;

    public TestTradePortalAdapter()
    {
        _innerService = new YourNamespace.TestService.webServices();
    }

    public string SubmitOrder(OrderRequest request)
    {
        return _innerService.SubmitOrder(request);
    }

    public OrderStatus GetOrderStatus(string orderId)
    {
        return _innerService.GetOrderStatus(orderId);
    }
}

如果两个服务的参数/返回值类型不完全一致,适配器里也可以做简单的类型转换,确保上层接口的一致性。

步骤3:基于配置的Autofac注册

接下来在Autofac容器里,根据配置文件的标识(比如AppSettings里的TradePortalEnvironment)来注册对应的适配器:

方式1:直接根据配置选择注册

var builder = new ContainerBuilder();
var environment = ConfigurationManager.AppSettings["TradePortalEnvironment"]; // 比如"Production"或"Test"

if (environment.Equals("Production", StringComparison.OrdinalIgnoreCase))
{
    builder.RegisterType<ProductionTradePortalAdapter>().As<ITradePortalService>().InstancePerDependency();
}
else
{
    builder.RegisterType<TestTradePortalAdapter>().As<ITradePortalService>().InstancePerDependency();
}

// 其他注册代码...
var container = builder.Build();

方式2:使用Autofac的条件注册(更灵活)

如果需要更复杂的条件判断,也可以用Autofac的条件注册:

builder.RegisterType<ProductionTradePortalAdapter>()
       .As<ITradePortalService>()
       .InstancePerDependency()
       .OnlyIf(_ => ConfigurationManager.AppSettings["TradePortalEnvironment"].Equals("Production", StringComparison.OrdinalIgnoreCase));

builder.RegisterType<TestTradePortalAdapter>()
       .As<ITradePortalService>()
       .InstancePerDependency()
       .OnlyIf(_ => ConfigurationManager.AppSettings["TradePortalEnvironment"].Equals("Test", StringComparison.OrdinalIgnoreCase));

步骤4:在业务代码中使用

现在你只需要在需要调用服务的地方注入ITradePortalService,完全不用关心底层是生产还是测试服务:

public class OrderService
{
    private readonly ITradePortalService _tradePortalService;

    public OrderService(ITradePortalService tradePortalService)
    {
        _tradePortalService = tradePortalService;
    }

    public void ProcessOrder(OrderRequest request)
    {
        var orderId = _tradePortalService.SubmitOrder(request);
        var status = _tradePortalService.GetOrderStatus(orderId);
        // 业务逻辑...
    }
}

额外优化:工厂类方案(可选)

如果你更倾向于用工厂类来控制实例创建,也可以注册一个工厂:

public class TradePortalServiceFactory
{
    public ITradePortalService CreateService()
    {
        var environment = ConfigurationManager.AppSettings["TradePortalEnvironment"];
        return environment.Equals("Production", StringComparison.OrdinalIgnoreCase)
            ? new ProductionTradePortalAdapter()
            : new TestTradePortalAdapter();
    }
}

// Autofac注册工厂
builder.RegisterType<TradePortalServiceFactory>().InstancePerDependency();

// 使用时注入工厂
public class OrderService
{
    private readonly ITradePortalService _tradePortalService;

    public OrderService(TradePortalServiceFactory factory)
    {
        _tradePortalService = factory.CreateService();
    }
}

这种方案的好处是完全解耦了服务实现和上层代码,后续如果新增第三个服务,只需要加一个适配器和修改配置判断即可,非常容易扩展。

内容的提问来源于stack exchange,提问作者r3plica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:41:18