WCF 学习笔记: ServiceHost

     WCF 服务的host方式主要有两种:self-hosting,active-hosting,举个例子:前者是指将wcf service 寄宿到console application上,后者则是将wcf service部署到IIS上。至于它们的好处嘛,感觉还是根据具体的需求来选择具体的途径。

     WCF service 在host之前,是可以对它进行一些修改,比如:添加behavior,endpoint。这些修改主要是用来修改Service Description类,因为service 在host的时候是需要根据该类来构建一系列的对象。

    贴一段关于service description的代码

            var serviceDescription = CreateServiceDescription();
            Console.WriteLine("{0, -17}: {1}", "Name", serviceDescription.Name);
            Console.WriteLine("{0, -17}: {1}", "Namespace", serviceDescription.Namespace);
            Console.WriteLine("{0, -17}: {1}", "ConfigurationName", serviceDescription.ConfigurationName);
            Console.WriteLine("{0, -17}: {1}", "Behaviors", serviceDescription.Behaviors[0].GetType().Name);
            for (int i = 1; i < serviceDescription.Behaviors.Count; i++)
            {
                Console.WriteLine("{0, -17}: {1}", "", serviceDescription.Behaviors[i].GetType().Name);
            }
            Console.WriteLine();
            for (int i = 1; i <= serviceDescription.Endpoints.Count; i++)
            {
                ServiceEndpoint endpoint = serviceDescription.Endpoints[i - 1];
                Console.WriteLine("第{0}个终结点", i);
                Console.WriteLine("\t{0, -9}: {1}", "Address", endpoint.Address);
                Console.WriteLine("\t{0, -9}: {1}", "Binding", endpoint.Binding);
                Console.WriteLine("\t{0, -9}: {1}", "Contract", endpoint.Contract.ContractType.Name);
                if (endpoint.Behaviors.Count > 0)
                {
                    Console.WriteLine("\t{0, -9}: {1}", "Behaviors", endpoint.Behaviors[0].GetType().Name);
                }
                for (int j = 1; j < endpoint.Behaviors.Count; j++)
                {
                    Console.WriteLine("\t{0, -9}: {1}", "", endpoint.Behaviors[j].GetType().Name);
                }
                Console.WriteLine();
            }

        static ServiceDescription CreateServiceDescription()
        {
            Type serviceType=typeof(CalculatorService);
            ServiceDescription description = new ServiceDescription();
            description.ServiceType = serviceType;
            var serviceBehaviors=(from item in serviceType.GetCustomAttributes(false)
                                             where item is IServiceBehavior
                                             select item as IServiceBehavior).ToArray();
            Array.ForEach(serviceBehaviors,(item)=>{description.Behaviors.Add(item);});

            if(description.Behaviors.Find<ServiceBehaviorAttribute>() ==null)
            {
                ServiceBehaviorAttribute behavior=new ServiceBehaviorAttribute();
                description.Behaviors.Add(behavior);
            }


            
            description.Name=description.Behaviors.Find<ServiceBehaviorAttribute>().Name;
            description.Namespace=description.Behaviors.Find<ServiceBehaviorAttribute>().Namespace;
            description.ConfigurationName = description.Behaviors.Find<ServiceBehaviorAttribute>().ConfigurationName;

            //load service behaviors from configuration file
            ServiceElement serviceElement = ConfigLoader.GetServiceElement(description.ConfigurationName);
            if (!string.IsNullOrEmpty(serviceElement.BehaviorConfiguration))
            {
                ServiceBehaviorElement behaviorElement = ConfigLoader.GetServiceBehaviorElement(serviceElement.BehaviorConfiguration);
                foreach (BehaviorExtensionElement extensionElemenet in behaviorElement)
                {
                    IServiceBehavior serviceBehavior = extensionElemenet.CreateBehavior() as IServiceBehavior;
                    description.Behaviors.Add(serviceBehavior);
                }
            }

            //add EndpointAdress from configuraiton file
            foreach (ServiceEndpointElement endpointElement in serviceElement.Endpoints)
            { 
                description.Endpoints.Add(CreateServiceEndpoint(serviceType,endpointElement));
                
            }
            return description;         
        }

wcf service 在host的时候有2种方式来生成必须的绑定元素,1)根据配置文件生产;2)动态绑定。贴两段关于动态生成Service Endpoint 和 Service Contract 的代码:

       static ServiceEndpoint CreateServiceEndpoint(Type serviceType, ServiceEndpointElement endpointElement)
        {
            //创建ServiceEndpoint
            EndpointAddress address = new EndpointAddress(endpointElement.Address);
            Binding binding = ConfigLoader.CreateBinding(endpointElement.Binding);
            ContractDescription contract = CreateContractDescription(serviceType, endpointElement.Contract);
            ServiceEndpoint endpoint = new ServiceEndpoint(contract, binding, address);

            //添加终结点行为
            if (!string.IsNullOrEmpty(endpointElement.BehaviorConfiguration))
            {
                EndpointBehaviorElement behaviorElement = ConfigLoader.GetEndpointBehaviorElement(endpointElement.BehaviorConfiguration);
                foreach (BehaviorExtensionElement extensionElement in behaviorElement)
                {
                    IEndpointBehavior endpointBehavior = (IEndpointBehavior)extensionElement.CreateBehavior();
                    endpoint.Behaviors.Add(endpointBehavior);
                }
            }
            return endpoint;
        }

        static ContractDescription CreateContractDescription(Type serviceType, string configurationName)
        {
            foreach (Type contract in serviceType.GetInterfaces())
            {
                ServiceContractAttribute serviceContractAttribute = contract.GetCustomAttributes(typeof(ServiceContractAttribute), false).FirstOrDefault() as ServiceContractAttribute;
                if (null != serviceContractAttribute)
                {
                    string configName = serviceContractAttribute.ConfigurationName ?? contract.Namespace + "." + contract.Name;
                    if (configurationName == configName)
                    {
                        return ContractDescription.GetContract(contract, serviceType);
                    }
                }
            }
            return null;
        }
    }
 ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                behavior.HttpGetEnabled = true;
                behavior.HttpGetUrl = new Uri(host.Description.Endpoints[0].Address.Uri.ToString() + "/mex");
                host.Description.Behaviors.Add(behavior);

                host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), host.Description.Endpoints[0].Address.Uri.ToString() + "/mex");

关于SVC文件的Factory属性,如果我们想在激活host在svc文件中的wcf时加入些自定义逻辑,我们可以为factory属性指定一个继承servicefactoryhostbase的类,该类的首个参数为service属性。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值