How to inject WCF service client in ASP.Net core?
Asked Answered
D

1

14

I have WCF service that I need to access from ASP.NET Core. I have installed WCF Connected Preview and created proxy successfully.

It created interface & client something like below

    [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
    }

The consumer class that calls the service looks like below

public class Consumer
{
  private IDocumentIntegration _client;
  public Consumer(IDocumentIntegration client)
  {
    _client = client;
  }

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

How do I register the IDocumentIntegration with ConfigureServices method in Startup class? I want to setup RemoteAddress & clientCredentials during the registration

  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)

    }
Danutadanya answered 27/9, 2016 at 18:55 Comment(2)
Did you tried using the factory method which is an overload to AddXxx methods?Calicut
That's what i thought. I was trying to use AddScoped.. but I would like to know the syntax?Danutadanya
C
31

Using the factory method overload seems suitable use case for it.

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

Where your appsettings would look like

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

Alternatively, inject the Options via options pattern. Since the DocumentIntegrationClient is partial, you can create a new file and add a parameterized constructor.

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

And create a options class

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

and populate it from appsettings.json.

services.Configure<DocumentServiceOptions>(Configuration.GetSection("MyService"));
Calicut answered 27/9, 2016 at 19:1 Comment(3)
Thanks this is exactly what I was looking for. I was getting error in my anonymous function syntaxDanutadanya
What is the proper way to consume from this service? It seems that maybe we should use transient service as that would allow the WCF service proxy to do it's own thing with regards to connection management. Just not sure exactly how this should look as far as calling close/abort on the proxy.El
@El I'm also curiousBloodline

© 2022 - 2024 — McMap. All rights reserved.