WCF 学习笔记: ServiceHost

来源:互联网 发布:unity3d ios 录屏处理 编辑:程序博客网 时间:2024/04/29 16:20

     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 0
原创粉丝点击