• 通过纯代码方式发布WCF服务


          网络上搜索WCF服务,一般是寄宿在IIS,通过WebConfig方式配服务地址,接口类型等信息,但是对于我这样的懒人,目前项目在开发阶段,实在不愿意每次添加新服务就更新配置文件,于是使用了反射来加载服务接口,并用控制台程序发布服务,贴上代码如下。
    
         
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using System.ServiceModel.Configuration;
    using Nebula.Proxy;
    using System.Reflection;
    using System.Configuration;
    using System.Xml;
    namespace MES_WCFService
    {
        public class HostIniter
        {
            public HostIniter()
            {
    
            }
            private ServiceHostCollection hosts;
    
            private Type[] interfaceTypes;
            private Type[] implTypes;
            private string addressBase;
            private string tcpPort;
            private string httpPort;
            private string basehttpPort;
            /// <summary>
            /// 通过反射获取所有服务接口及其实现类
            /// </summary>
            private void ScanService()
            {
                interfaceTypes = Assembly.Load(ConfigurationManager.AppSettings["interfaceDLLName"]).GetTypes();
                implTypes = Assembly.Load(ConfigurationManager.AppSettings["implDLLName"]).GetTypes();
    
            }
    
            public ServiceHostCollection InitHost()
            {
                
                hosts = new ServiceHostCollection();
                addressBase = ConfigurationManager.AppSettings["baseAddress"];
                tcpPort = ConfigurationManager.AppSettings["tcpPort"];
                httpPort = ConfigurationManager.AppSettings["httpPort"];
                basehttpPort = ConfigurationManager.AppSettings["basehttpPort"];
                ScanService();
                foreach (Type implType in implTypes)
                {
                    try
                    {
    
                        if (!typeof(IWCFService).IsAssignableFrom(implType))
                        {
                            continue;
                        }
                        string baseNameSpace= "http://" + addressBase + ":" + httpPort + "/WCFService/";
                        string address = baseNameSpace + implType.Name;
                        Uri baseAddress = new Uri(address);
                        ServiceHost host = new ServiceHost(implType, baseAddress);  //
                        Console.WriteLine("Add:" + implType.FullName);
                        Console.WriteLine("Address:" + address);
                        host.Description.Namespace = baseNameSpace;
                        host.Description.Name = implType.Name;
                        
                        
    
                        ServiceSecurityAuditBehavior secBehacior = new ServiceSecurityAuditBehavior();
    
    
    
                        secBehacior.MessageAuthenticationAuditLevel = AuditLevel.None;
                        secBehacior.ServiceAuthorizationAuditLevel = AuditLevel.None;
    
                        host.Description.Behaviors.Add(secBehacior);
                          
                        //   secBehacior.   
    
    
    
                        ServiceMetadataBehavior metaBehavior = new ServiceMetadataBehavior();
                        metaBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                        metaBehavior.HttpGetEnabled = true;
                        
                  
                        ServiceDebugBehavior debugBehavior = host.Description.Behaviors[typeof(ServiceDebugBehavior)] as ServiceDebugBehavior;
                        debugBehavior.IncludeExceptionDetailInFaults = true;
                     
    
                        host.Description.Behaviors.Add(metaBehavior);
    
                        Type t = host.GetType();
                        object obj = t.Assembly.CreateInstance("System.ServiceModel.Dispatcher.DataContractSerializerServiceBehavior", true,
                        BindingFlags.CreateInstance | BindingFlags.Instance |
                        BindingFlags.NonPublic, null, new object[] { false, Int32.MaxValue },
                        null, null);
                        IServiceBehavior myServiceBehavior = obj as IServiceBehavior;
                        if (myServiceBehavior != null)
                        {
                            host.Description.Behaviors.Add(myServiceBehavior);
                            //  Console.WriteLine("Add DataContractSerializerServiceBehavior !");
                        }
    
    
                        ////host.Description.Behaviors.Add(debugBehavior);
                        foreach (Type interfaceType in interfaceTypes)
                        {
                            if (interfaceType == typeof(IWCFService))
                            {
                                continue;
                            }
    
                            if (interfaceType.IsAssignableFrom(implType))
                            {
                                //本来是WSHttpBinding 为了让Java能调用到这些服务,遂改BasicHttpBinding
                                
                                BasicHttpBinding wsBinding = new BasicHttpBinding();
                                wsBinding.Security.Mode =BasicHttpSecurityMode.None;
                                wsBinding.MaxBufferPoolSize = 524288;
                                wsBinding.MaxReceivedMessageSize = int.MaxValue;
                                
                                wsBinding.ReaderQuotas.MaxStringContentLength = 0xfffffff;
                                wsBinding.ReaderQuotas.MaxArrayLength = 0xfffffff;
                                wsBinding.ReaderQuotas.MaxBytesPerRead = 0xfffffff;
                                wsBinding.ReaderQuotas.MaxDepth = 0xfffffff;
                                wsBinding.MessageEncoding = WSMessageEncoding.Text;
                                wsBinding.TextEncoding = Encoding.UTF8;
                                wsBinding.OpenTimeout = new TimeSpan(0, 30, 0);
                                wsBinding.ReceiveTimeout = new TimeSpan(0, 30, 0);
                                wsBinding.SendTimeout = new TimeSpan(0, 30, 0);
                               
                                ContractDescription contractDescription = ContractDescription.GetContract(interfaceType);
                                ServiceEndpoint httpEndpoint = new ServiceEndpoint(contractDescription, wsBinding, new EndpointAddress(baseAddress));
                                httpEndpoint.Name = "http" + implType.Name;
                                host.Description.Endpoints.Add(httpEndpoint);
    
                                NetTcpBinding netTcpBinding = new NetTcpBinding() { Security = new NetTcpSecurity { Mode = SecurityMode.None } };
                                netTcpBinding.Security.Mode = SecurityMode.None;
                                netTcpBinding.MaxBufferPoolSize = 524288;
                                netTcpBinding.MaxReceivedMessageSize = int.MaxValue;
                                netTcpBinding.ReaderQuotas.MaxStringContentLength = 0xfffffff;
                                netTcpBinding.ReaderQuotas.MaxArrayLength = 0xfffffff;
                                netTcpBinding.ReaderQuotas.MaxBytesPerRead = 0xfffffff;
                                netTcpBinding.ReaderQuotas.MaxDepth = 0xfffffff;
                                netTcpBinding.OpenTimeout = new TimeSpan(0, 30, 0);
                                netTcpBinding.ReceiveTimeout = new TimeSpan(0, 30, 0);
                                netTcpBinding.SendTimeout = new TimeSpan(0, 30, 0);
                                ServiceEndpoint tcpEndpoint = new ServiceEndpoint(contractDescription, netTcpBinding, new EndpointAddress("net.tcp://" + addressBase + ":" + tcpPort + "/WCFService/" + implType.Name));
                                tcpEndpoint.Name = "tcp" + implType.Name;
                                host.Description.Endpoints.Add(tcpEndpoint);
    
    
    
    
    
                                host.AddServiceEndpoint(
                                    ServiceMetadataBehavior.MexContractName,
                                    MetadataExchangeBindings.CreateMexHttpBinding(),
                                    "mex"
                                );
    
                                break;
                            }
                        }
                        //添加自定义的 Behavior
                        host.Description.Behaviors.Add(new MesServiceInterceptorAttribute());
    
    
                        hosts.Add(host);
                    }
    
    
                    catch (Exception commProblem)
                    {
    
                        Console.WriteLine("There was a  problem with this type ;"+implType.FullName);
                        Console.WriteLine("Message:" + commProblem.Message);
                        Console.WriteLine("StackTrace:" + commProblem.StackTrace);
                        Console.Read();
                    }
    
                }
                return hosts;
            }
    
        }
    }
    MesServiceInterceptorAttribute的代码
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel.Description;
    using System.ServiceModel;
    using System.Collections.ObjectModel;
    using System.ServiceModel.Channels;
    
    namespace MES_WCFService
    {
        [AttributeUsage(AttributeTargets.Class)]
        public class MesServiceInterceptorAttribute : Attribute, IServiceBehavior
        {
            protected MesOperationInterceptorAttribute CreateOperationInterceptor()
            {
                return new MesOperationInterceptorAttribute();
            }
    
            public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase host)
            {
                foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
                {
                    foreach (OperationDescription operation in endpoint.Contract.Operations)
                    {
                        bool checkresult = false;
                        foreach (IOperationBehavior behavior in operation.Behaviors)
                        {
                            if (behavior is MesOperationInterceptorAttribute)
                            {
                                checkresult = true;
                                break;
                            }
                        }
                        if (!checkresult)
                        {
                            operation.Behaviors.Add(CreateOperationInterceptor());
                        }
                    }
                }
            }
            public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
            { }
    
            public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            { }
        }
    }
    MesOperationInterceptorAttribute的:
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using System.ServiceModel.Description;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher;
    namespace MES_WCFService
    {
        [AttributeUsage(AttributeTargets.Method)]
        public class MesOperationInterceptorAttribute : Attribute, IOperationBehavior
        {
           //private InterceptionType m_InteType = InterceptionType.None;
            private string _operatName;
        public MesOperationInterceptorAttribute() { }
    
    //public MesOperationInterceptorAttribute(InterceptionType inteType)
    //{
    //    this.m_InteType = inteType;
    //}
    
        protected MesInvoker CreateInvoker(IOperationInvoker oldInvoker)
        {
            return new MesInvoker(oldInvoker, _operatName);
        }
    
        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        { }
    
        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        { }
    
        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            IOperationInvoker oldInvoker = dispatchOperation.Invoker;
            _operatName = dispatchOperation.Name;
            dispatchOperation.Invoker = CreateInvoker(oldInvoker);
        }
    
        public void Validate(OperationDescription operationDescription)
        { }
        }
    }
  • 相关阅读:
    电脑自动登录
    修改电脑AppData位置
    MySQL_Navicat for MySQL设置定时备份
    MySQL_获取2个日期之间的所有日期
    MySQL_分页优化
    MySQL_1055错误代码与sql_mode = only_full_group_by不兼容
    MySQL_通过Binlog日志恢复数据库
    【Windows核心编程】如何知道程序运行中当前操作的内存地址范围,自己实现一个文件映射类
    整理后JS基础的封装
    git从本地仓库迁移到远程仓库
  • 原文地址:https://www.cnblogs.com/wangchuang/p/5820495.html
Copyright © 2020-2023  润新知