如何从配置中动态传递端点详细信息?

时间:2017-05-09 16:33:28

标签: wcf asp.net-core

我跟着article将WCF服务包含到我的ASP.NET核心应用程序中。

在reference.cs中查看下面的行,似乎默认端点配置在reference.cs中是硬编码的。

return new System.ServiceModel.EndpointAddress("http://localhost:49945/SimpleService.svc");

这就是我在asp.net核心控制器中创建客户端的方法 -

BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
            EndpointAddress endpointAddress = new EndpointAddress("http://localhost:49945/SimpleService.svc");
            wcfClient = new SimpleServiceClient(basicHttpBinding, endpointAddress);

所以我的问题是 -

  1. 我应该在哪里维护端点详细信息,以便在部署期间轻松配置?

  2. 如何从配置文件(appsetting.json)动态传递端点详细信息(地址和绑定)

  3. 生成的Reference.cs文件如下所示 -

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     This code was generated by a tool.
    //     //
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    namespace SimpleServiceReference
    {
        using System.Runtime.Serialization;
    
    
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.5.0.0")]
        [System.Runtime.Serialization.DataContractAttribute(Name="CompositeType", Namespace="http://schemas.datacontract.org/2004/07/SimpleService")]
        public partial class CompositeType : object
        {
    
            private bool BoolValueField;
    
            private string StringValueField;
    
            [System.Runtime.Serialization.DataMemberAttribute()]
            public bool BoolValue
            {
                get
                {
                    return this.BoolValueField;
                }
                set
                {
                    this.BoolValueField = value;
                }
            }
    
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string StringValue
            {
                get
                {
                    return this.StringValueField;
                }
                set
                {
                    this.StringValueField = value;
                }
            }
        }
    
        [System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.5.0.0")]
        [System.ServiceModel.ServiceContractAttribute(ConfigurationName="SimpleServiceReference.ISimpleService")]
        public interface ISimpleService
        {
    
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ISimpleService/GetData", ReplyAction="http://tempuri.org/ISimpleService/GetDataResponse")]
            System.Threading.Tasks.Task<string> GetDataAsync(int value);
    
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ISimpleService/GetDataUsingDataContract", ReplyAction="http://tempuri.org/ISimpleService/GetDataUsingDataContractResponse")]
            System.Threading.Tasks.Task<SimpleServiceReference.CompositeType> GetDataUsingDataContractAsync(SimpleServiceReference.CompositeType composite);
        }
    
        [System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.5.0.0")]
        public interface ISimpleServiceChannel : SimpleServiceReference.ISimpleService, System.ServiceModel.IClientChannel
        {
        }
    
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.5.0.0")]
        public partial class SimpleServiceClient : System.ServiceModel.ClientBase<SimpleServiceReference.ISimpleService>, SimpleServiceReference.ISimpleService
        {
    
        /// <summary>
        /// Implement this partial method to configure the service endpoint.
        /// </summary>
        /// <param name="serviceEndpoint">The endpoint to configure</param>
        /// <param name="clientCredentials">The client credentials</param>
        static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);
    
            public SimpleServiceClient() : 
                    base(SimpleServiceClient.GetDefaultBinding(), SimpleServiceClient.GetDefaultEndpointAddress())
            {
                this.Endpoint.Name = EndpointConfiguration.BasicHttpBinding_ISimpleService.ToString();
                ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
            }
    
            public SimpleServiceClient(EndpointConfiguration endpointConfiguration) : 
                    base(SimpleServiceClient.GetBindingForEndpoint(endpointConfiguration), SimpleServiceClient.GetEndpointAddress(endpointConfiguration))
            {
                this.Endpoint.Name = endpointConfiguration.ToString();
                ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
            }
    
            public SimpleServiceClient(EndpointConfiguration endpointConfiguration, string remoteAddress) : 
                    base(SimpleServiceClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress))
            {
                this.Endpoint.Name = endpointConfiguration.ToString();
                ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
            }
    
            public SimpleServiceClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) : 
                    base(SimpleServiceClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress)
            {
                this.Endpoint.Name = endpointConfiguration.ToString();
                ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
            }
    
            public SimpleServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
                    base(binding, remoteAddress)
            {
            }
    
            public System.Threading.Tasks.Task<string> GetDataAsync(int value)
            {
                return base.Channel.GetDataAsync(value);
            }
    
            public System.Threading.Tasks.Task<SimpleServiceReference.CompositeType> GetDataUsingDataContractAsync(SimpleServiceReference.CompositeType composite)
            {
                return base.Channel.GetDataUsingDataContractAsync(composite);
            }
    
            public virtual System.Threading.Tasks.Task OpenAsync()
            {
                return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndOpen));
            }
    
            public virtual System.Threading.Tasks.Task CloseAsync()
            {
                return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginClose(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndClose));
            }
    
            private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
            {
                if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_ISimpleService))
                {
                    System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
                    result.MaxBufferSize = int.MaxValue;
                    result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
                    result.MaxReceivedMessageSize = int.MaxValue;
                    result.AllowCookies = true;
                    return result;
                }
                throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
            }
    
            private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration)
            {
                if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_ISimpleService))
                {
                    return new System.ServiceModel.EndpointAddress("http://localhost:49945/SimpleService.svc");
                }
                throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
            }
    
            private static System.ServiceModel.Channels.Binding GetDefaultBinding()
            {
                return SimpleServiceClient.GetBindingForEndpoint(EndpointConfiguration.BasicHttpBinding_ISimpleService);
            }
    
            private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress()
            {
                return SimpleServiceClient.GetEndpointAddress(EndpointConfiguration.BasicHttpBinding_ISimpleService);
            }
    
            public enum EndpointConfiguration
            {
    
                BasicHttpBinding_ISimpleService,
            }
        }
    }
    

1 个答案:

答案 0 :(得分:3)

我过去需要相同的东西,最后在应用程序的选项中存储WCF服务的连接详细信息。我将详细信息存储在appsettings.json文件中,创建了一个Options类,并将其注册到服务设置逻辑中,以便在创建WCF服务时请求它。

裸露我的代码,我只是快速地掀起了这个。我没有测试它的常见错误,如缺少大括号,分号或拼写错误:-P

选项类

public class MyServiceOptions
{
    public string EndpointUrl {get;set;}
}

摘自startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyServiceOptions>Configuration.GetSection("MyService"));
    //Other calls as needed...

}

<强> appsettings.json

{
    "MyService": {
        "EndpointUrl": "http://localhost:49945/SimpleService.svc"
    }
}

然后,您可以通过各种方式从依赖项注入容器中请求IOptions<MyServiceOptions>的实例来访问您的选项。

public class MyController : Controller
{
    //Option 1, in controller constructor
    private IOptions<MyServiceOptions> myOptions;

    public MyController(IOptions<MyServiceOptions> myOptions1)
    {
        myOptions = myOptions1
    }

    //Option 2, in action method signature
    public IActionResult MyAction([FromServices]IOptions<MyServiceOptions> myOptions2)
    {
        //Option 3, directly
        var myOptions3 = HttpContext.RequestServices.GetService<IControllerFactory>();
        //NOTE: The GetService<>() method is an extension method from the Microsoft.Extensions.DependencyInjection namespace


        BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
        EndpointAddress endpointAddress = new EndpointAddress(myOptions.Value.EndpointUrl);
        wcfClient = new SimpleServiceClient(basicHttpBinding, endpointAddress);
    }
}