如何在ASP.Net Core中注入WCF服务客户端?

14
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我有一个WCF服务,需要从ASP.NET Core访问。我已经安装了WCF Connected Preview并成功创建了代理。

它创建了以下类似的接口和客户端

    [System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.3.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.IDocumentIntegration")]
    public interface IDocumentIntegration
    {

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDocumentIntegration/SubmitDocument", ReplyAction="http://tempuri.org/IDocumentIntegration/SubmitDocumentResponse")]
        [System.ServiceModel.FaultContractAttribute(typeof(ServiceReference1.FaultDetail), Action="http://tempuri.org/IDocumentIntegration/SubmitDocumentFaultDetailFault", Name="FaultDetail", Namespace="http://schemas.datacontract.org/2004/07/MyCompany.Framework.Wcf")]
        System.Threading.Tasks.Task<string> SubmitDocumentAsync(string documentXml);
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.3.0.0")]
    public interface IDocumentIntegrationChannel : ServiceReference1.IDocumentIntegration, System.ServiceModel.IClientChannel
    {
    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.3.0.0")]
    public partial class DocumentIntegrationClient : System.ServiceModel.ClientBase<ServiceReference1.IDocumentIntegration>, ServiceReference1.IDocumentIntegration
    { 
      // constructors and methods here
    }

调用该服务的消费者类如下所示。
public class Consumer
{
  private IDocumentIntegration _client;
  public Consumer(IDocumentIntegration client)
  {
    _client = client;
  }

  public async Task Process(string id)
  {  
     await _client.SubmitDocumentAsync(id);
  }
} 

我应该如何在Startup类的ConfigureServices方法中注册IDocumentIntegration?我想在注册过程中设置RemoteAddress和clientCredentials。
  public void ConfigureServices(IServiceCollection services)
    {
        services.AddApplicationInsightsTelemetry(Configuration);
        services.AddMvc();

        // how do I inject DocumentIntegrationClient here??
        var client = new DocumentIntegrationClient();            
        client.ClientCredentials.UserName.UserName = "myusername";
        client.ClientCredentials.UserName.Password = "password";
        client.Endpoint.Address = new EndpointAddress(urlbasedonenvironment)

    }

1
你尝试过使用工厂方法吗?它是AddXxx方法的一种重载。 - Tseng
1
这正是我想的。我试图使用AddScoped..但我想知道语法是什么? - LP13
1个回答

31

使用工厂方法的重载似乎是一个合适的使用场景。

services.AddScoped<IDocumentIntegration>(provider => {
    var client = new DocumentIntegrationClient();

    // Use configuration object to read it from appconfig.json
    client.ClientCredentials.UserName.UserName = Configuration["MyService:Username"];
    client.ClientCredentials.UserName.Password = Configuration["MyService:Password"];
    client.Endpoint.Address = new EndpointAddress(Configuration["MyService:BaseUrl"]);

    return client;
});

你的appsettings应该看起来像什么

{
    ...
    "MyService" : 
    {
        "Username": "guest",
        "Password": "guest",
        "BaseUrl": "http://www.example.com/"
    }
}

或者,通过选项模式注入选项。由于DocumentIntegrationClient是partial的,因此您可以创建一个新文件并添加带参数的构造函数。

public partial class DocumentIntegrationClient :
    System.ServiceModel.ClientBase<ServiceReference1.IDocumentIntegration>, ServiceReference1.IDocumentIntegration
{
    public DocumentIntegrationClient(IOptions<DocumentServiceOptions> options) : base()
    {
        if(options==null)
        {
            throw new ArgumentNullException(nameof(options));
        }

        this.ClientCredentials.Username.Username = options.Username;
        this.ClientCredentials.Username.Password = options.Password;
        this.Endpoint.Address = new EndpointAddress(options.BaseUrl);
    }
}

创建一个选项类

public class DocumentServiceOptions
{
    public string Username { get; set; } 
    public string Password { get; set; }
    public string BaseUrl { get; set; }
}

并从appsettings.json中填充它。

services.Configure<DocumentServiceOptions>(Configuration.GetSection("MyService"));

1
谢谢,这正是我在寻找的。我的匿名函数语法出现了错误。 - LP13
8
从这个服务中消费的正确方式是什么?似乎我们应该使用短暂服务,这将允许WCF服务代理对连接管理做自己的事情。只是不确定在调用代理的close/abort时应该如何处理。 - scuba88
1
@scuba88 我也很好奇 - Amoz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接