Code4fun: one service, one config

Source: Internet
Author: User
Tags webhost

The bearer of WCF can be implemented either through code or config. in addition, the configuration is more conducive to future maintenance and expansion. by default, WCF writes all service configurations to a config file. this method is more conducive to professional IT staff for centralized management of services. in many projects, this method can also solve the division of labor problem. however, it also has some drawbacks. For example, if an insignificant service change requires a Config changeProgramAny modifications to config are very likely to cause application restart or exceptions. for example, if you change the Web. config will cause session and application loss. these situations will affect the user experience. this article uses the custom servicehost method to implement a Service corresponds to a config file, so that when a service is modified, the Administrator only needs to change the corresponding config file. Better isolation between services.

1) Implementation ideas and key points of custom configuration files

In servicehostbase, the parent class of servicehost, there is a method closely related to the configuration file loading, which is:

 
Protected virtual voidApplyconfiguration ();

This method is used to convert the configuration information under the <system. servicemodel> node in the application configuration file to the specific service settings of WCF. Then rewrite this method to achieve the above purpose.

2) custom configuration file Policy

The default policy is that the service and configuration are many-to-one. A Configuration contains all service configurations. The configuration file is the configuration file of the default application. It is Web. config on the website, and in Windows applications, the configuration file is the application name. config. The custom Configuration Policy to be implemented in this article is that a service corresponds to a configuration file, and the name of the configuration file is the full name of the service. For example, if a service is named Robin. WCF. onetoone. Services. calculator, the corresponding service configuration file name is Robin. WCF. onetoone. Services. Calculator. config. You also need to consider the location of this file. We develop a policy: the custom service configuration file and the default application configuration file are stored in the same directory.

Implementation process:

Step 1: create a solution named "Robin. WCF. onetoone" and add three projects to the solution:

Robin. WCF. onetoone. servicelib

Robin. WCF. onetoone. Services

Robin. WCF. onetoone. Services. Web

The functions of these three projects are as follows:

Robin. WCF. onetoone. servicelib is used to create contracts and implement services, and to create custom servicehost and custom servicehostfactory

Robin. WCF. onetoone. Services is a self-managed service for Robin. WCF. onetoone. servicelib.

Robin. WCF. onetoone. Services. Web is the IIS hosting service for Robin. WCF. onetoone. servicelib.

Step 2: implement services

Create two files in Robin. WCF. onetoone. servicelib: icalculator. CS and calculator. CS, which are used for service contract and service implementation respectively.CodeAs follows:

Icalculator. CS

 
UsingSystem;UsingSystem. Collections. Generic;UsingSystem. LINQ;UsingSystem. text;UsingSystem. servicemodel;NamespaceRobin. WCF. onetoone. Services {[Servicecontract]Public interfaceIcalculator{[Operationcontract]IntAdd (IntA,IntB );}}

Calculator. CS

UsingSystem;UsingSystem. Collections. Generic;UsingSystem. LINQ;UsingSystem. text;NamespaceRobin. WCF. onetoone. Services {Public classCalculator:Icalculator{Public intAdd (IntA,IntB ){ReturnA + B ;}}}

The implemented service is very simple, because our goal is not to implement complicated business logic, but the key is to modify the usage of the framework.

Step 3: implement a custom servicehost named myservicehost.

 Using System; Using System. Collections. Generic; Using System. LINQ; Using System. text; Using System. servicemodel; Using System. servicemodel. configuration; Using System. configuration; Namespace Robin. WCF. onetoone. Services { Public class  Myservicehost : Servicehost { Public Myservicehost ( Object Singletoninstance, Params  Uri [] Baseaddresses ): Base (Singletoninstance, baseaddresses ){} Public Myservicehost ( Type Servicetype, Params  Uri [] Baseaddresses ): Base (Servicetype, baseaddresses ){} /// <Summary> ///  Override applyconfiguration to load config from custom file  /// </Summary>  Protected override void Applyconfiguration (){// Get custom config file name by our rule: config file name = servicetype. Name  VaR Myconfigfilename = This . Description. servicetype. fullname; // Get config file path  String Dir = system. Appdomain . Currentdomain. setupinformation. applicationbase; String Myconfigfilepath = system. Io. Path . Combine (Dir, myconfigfilename + ". Config" ); If (! System. Io. File . Exists (myconfigfilepath )){ Base . Applyconfiguration (); Return ;} VaR Configfilemap = New System. configuration. Execonfigurationfilemap (); Configfilemap. execonfigfilename = myconfigfilepath; VaR Config = system. configuration. Configurationmanager . Openmappedexeconfiguration (configfilemap, Configurationuserlevel . None ); VaR Servicemodel = system. servicemodel. configuration.Servicemodelsectiongroup . Getsectiongroup (config ); If (Servicemodel = Null ){ Base . Applyconfiguration (); Return ;} Foreach ( Serviceelement Serviceelement In Servicemodel. Services. Services ){ If (Serviceelement. Name = This . Description. servicetype. fullname) {loadconfigurationsection (serviceelement ); Return ;}}Throw new  Exception ( "There is no service element match the description! " );}}}

In the custom servicehost, the full name of the service, that is, the full name of the service, is implemented by overwriting the applyconfiguration method.This. Description. servicetype. fullname is used as the configuration file name, and still uses. config as the suffix. Use the path of the default application configuration file as the path of the custom configuration file. The default configuration file path can be obtained as follows:

 
StringDir = system.Appdomain. Currentdomain. setupinformation. applicationbase;
 
The following code segment solves the problem of using a custom file as a system configuration file:
VaRConfigfilemap =NewSystem. configuration.Execonfigurationfilemap(); Configfilemap. execonfigfilename = myconfigfilepath;VaRConfig = system. configuration.Configurationmanager. Openmappedexeconfiguration (configfilemap,Configurationuserlevel. None );
 
The final config is an instance of the system. configuration. configuration category.
 
After using the custom file as the configuration object and generating the configuration object, you need to find the servicemodesectiongroup in the configuration object, and then obtain
 
Serviceelement with the same name as the service to be hosted. The method is shown in the following code:
  var  servicemodel = system. servicemodel. configuration.  servicemodelsectiongroup . getsectiongroup (config);  If  (servicemodel =  null ) { base . applyconfiguration ();  return ;}< span style = "color: Blue "> foreach  ( serviceelement  serviceelement  in  servicemodel. services. services) { If  (serviceelement. name =  This . description. servicetype. fullname) {loadconfigurationsection (serviceelement);  return ;}< span style = "color: Blue"> THR Ow new   exception  (" there is no service element match the description! "); 

Finally, if the node matching the bearer service cannot be found in the configuration, an exception is thrown.

Step 4: implement the custom servciehostfactory: myservicehostfactory

If the host is a consol application or other non-web application, you can implement the third step. However. in SVC, the factory of the specified servicehost is not displayed. By default, servicehostfactory is used, while servicehostfactory generates the servicehost object. To use the custom myservicehost in the previous step, to implement a custom servciehostfactory, the implementation code is very simple:

 Using System; Using System. Collections. Generic; Using System. LINQ; Using System. text; Using System. servicemodel. activation; Using System. servicemodel; Using System. reflection;Namespace Robin. WCF. onetoone. Services { Public class  Myservicehostfactory : Servicehostfactory { Protected override System. servicemodel. Servicehost Createservicehost ( Type Servicetype, Uri [] Baseaddresses ){ Return new  Myservicehost (Servicetype, baseaddresses );}}}

In fact, the createservicehost method returnsMyservicehostYou can.

Step 5: Implement console bearer

In Robin. WCF. onetoone. services, create a config file named: Robin. WCF. onetoone. services. calculator. config. Note that the name is consistent with the full name of the implemented service. Set the content:

 

 <?  XML  Version  = " 1.0 " Encoding  = " UTF-8 " ?> <  Configuration  > <  System. servicemodel  > < Services  > <  Service  Name  = " Robin. WCF. onetoone. Services. Calculator " > <  Host  > <  Baseaddresses  > <  Add  Baseaddress  = " Http: // 127.0.0.1: 5698 " /> </ Baseaddresses  > </  Host  > <  Endpoint  Address  = " Calculator " Binding  = " Wshttpbinding " Contract  = " Robin. WCF. onetoone. Services. icalculator " > </ Endpoint  > </  Service  > </  Services  > </  System. servicemodel  > </  Configuration  > 

Note that the custom configuration file must also be consistent with the configuration file format of the default application.<Configuration>Node.

Then, set programe. CS code:

 Using System; Using System. Collections. Generic; Using System. LINQ; Using System. text; Namespace Robin. WCF. onetoone. Services { Public class  Programe { Static void Main ( String [] ARGs ){ Using ( Myservicehost Host = New  Myservicehost ( Typeof (Calculator ) {Host. Opened + = New  Eventhandler ( Delegate ( Object Sender, Eventargs E ){ Console . Writeline ( "Service is opened! " ); Foreach ( VaR Channeldiapacher In Host. channeldispatchers ){ Console . Writeline ("Listen URL :" + Channeldiapacher. listener. Uri. tostring () ;}}); host. open ();} Console . Read ();}}}

Step 6: Implement IIS bearer

In Robin. WCF. onetoone. services. in the Web, first reference Robin. WCF. onetoone. servicelib, and then add a custom configuration file: Robin. WCF. onetoone. services. calculator. config. Code:

 

 <?  XML  Version  = " 1.0 " Encoding  = " UTF-8 " ?> < Configuration  > <  System. servicemodel  > <  Services  > <  Service  Name  = " Robin. WCF. onetoone. Services. Calculator " Behaviorconfiguration  = " Robin. WCF. onetoone. webhost. service1behavior " > <  Endpoint Binding  = " Wshttpbinding " Contract  = " Robin. WCF. onetoone. Services. icalculator " > </  Endpoint  > </  Service  > </  Services  > <  Behaviors  > <  Servicebehaviors > <  Behavior  Name  = " Robin. WCF. onetoone. webhost. service1behavior " > <  Servicemetadata  Httpgetenabled  = " True " /> <  Servicedebug  Includeexceptiondetailinfaults  = " True "/> </  Behavior  > </  Servicebehaviors  > </  Behaviors  > </  System. servicemodel  > </  Configuration  > 

Change the Code of Service. SVC:

<%@ServicehostLanguage= "C #"Debug= "True"Service= "Robin. WCF. onetoone. Services. Calculator"Factory= "Robin. WCF. onetoone. Services. myservicehostfactory"%>
 
 

Note:Service andFactory.

 

The next step is to verify whether our implementation is feasible. Start Robin. WCF. onetoone. Services and get the following program output:

Based on the above code, we can find that the configuration in Robin. WCF. onetoone. Services. Calculator. config has achieved the expected results. Indicates that it is feasible in the console.

 

Start service. SVC in Robin. WCF. onetoone. Services. Web. The following output is displayed:

It indicates that it also works normally in IIS.

 

References:

Custom config file for a WCF Service hosted in IIS

 

Sample Code: http://files.cnblogs.com/jillzhang/Robin.Wcf.OnetoOne.rar

 

Next topic: one host, movie service!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.