【问题标题】:How to inject WCF service client in ASP.Net core?如何在 ASP.Net 核心中注入 WCF 服务客户端?
【发布时间】:2016-09-27 18:55:20
【问题描述】:

我有需要从 ASP.NET Core 访问的 WCF 服务。我已经安装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)

    }

【问题讨论】:

  • 您是否尝试过使用工厂方法,它是 AddXxx 方法的重载?
  • 我就是这么想的。我试图使用 AddScoped.. 但我想知道语法?

标签: c# asp.net-core .net-core coreclr


【解决方案1】:

使用工厂方法重载似乎是合适的用例。

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 是部分的,您可以创建一个新文件并添加参数化构造函数。

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"));

【讨论】:

  • 谢谢,这正是我想要的。我的匿名函数语法出现错误
  • 从该服务中消费的正确方法是什么?似乎我们应该使用瞬态服务,因为这将允许 WCF 服务代理在连接管理方面做自己的事情。只是不确定在代理上调用 close/abort 应该是什么样子。
猜你喜欢
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
  • 2017-07-02
  • 1970-01-01
  • 2020-03-09
相关资源
最近更新 更多