SO-Aware the new tool from Tellago Studios is a Service repository, that allows you to centralize the configuration so that it can be consumed by both the service and the client. This helps you solve things like versioning, environment specific configuration and integration problems. In this post we'll go through creating the configuration for our service and then setting up the service and the client.
Service configurationCreating the service configuration in SO-Aware is pretty straight forward thanks to the website that is provided with SO-Aware installation. But if you want/need to set up the services programatically, you can do that through the OData RESTful API provided. For this example, we'll use the service and client provided in the SO-Aware SDK which you can download from this link. You will need to add the following dlls to your service project: Tellago.ServiceModel.Governance.Hosting Tellago.ServiceModel.Governance.ServiceConfiguration And add the following references to your client: Tellago.ServiceModel.Governance.Resources.Client Tellago.ServiceModel.Governance.ServiceConfiguration (all of the dlls are available in the SDK)
Creating the serviceIn order to set up your service, first you need to create the service. In our example we'll name our service "People Finder", you can see the form here: The namespace field should be the namespace of the ServiceContract. the Messaging style should be one of: SOAP, REST or OData. Categories can be any type of categorization you might find useful. After you create the service, a new section "Service Versions" will appear. SO-Aware helps you keep your services versioned by managing these "Service Versions" right here. So next thing we'll do is create our first version (1.0). After you enter the WSDL Url, you have to paste the WSDL xml into the WSDL field. SO-Aware will process this information and store it so it can later create either the service or the client's endpoint. When creating a service version in SO-Aware you might have a notification in the upper right corner like the following. This notification has a very cool feature, which is that it will give you access to more detailed information about the error. If you hit the "more details" link, it will show you the stack trace of the error. In case you have an exception like the following: ... at System.Data.Services.DataService`1.BatchDataService.HandleBatchContent(Stream responseStream) XML Parsing: line 1, character 8, text/xmldecl not at the beginning of input System.Data.SqlClient.SqlException at ... This might be due to blank spaces at the beginning of your WSDL field. You might get one of these errors if you copy and paste the wsdl from IE. The character number 8 might change, and depends on the amount of blank spaces. If the details contain the following XML Parsing error: "line 1, character 39, unable to switch the encoding" Then all you have to do is remove the encoding attribute from the xml declaration, For example: original: <?xml version="1.0" encoding="utf-8" ?> fixed: <?xml version="1.0" ?> Once we have our Service Version in place, we can set the binding and behavior configurations, and also set up tests for each operation (not covered in this post). In our example (and despite of the endpoint name), we will set up the endpoint to use "basicHttp". SO-Aware comes with quite a few endpoint bindings out of the box, and you can create your own templates too. Now that we have our endpoint configuration covered, we'll go ahead and consume this from the service and the client.
Using configuration from the WCF ServiceIn order to use the configuration stored in SO-Aware from our service, we will have to use the ServiceHostFactory provided by SO-Aware and set up a minimum configuration in the config file. In order to use the ServiceHostFactory provided by SO-Aware, you have to go to your .svc file, right click on it, and hit on View Markup. In your markup you will add a "Factory" attribute with SO-Aware's factory as shown in the following code:
Our new factory needs to know the url for the Service Repository, and which service we are trying to expose. We can do that by adding SO-Aware configuration in the web.config. Inside Configuration/ConfigSections add the following
<%@ ServiceHost Language="C#" Service="Tellago.ServiceModel.Governance.SDK.PeopleFinderService" CodeBehind="PeopleFinder.svc.cs" Factory="Tellago.ServiceModel.Governance.Hosting.ConfigurableServiceHostFactory" %>
And the serviceRepository section looks like:
<section name="serviceRepository" type="Tellago.ServiceModel.Governance.ServiceConfiguration.ServiceRepositoryConfigurationSection, Tellago.ServiceModel.Governance.ServiceConfiguration" />
Notice how the name of the service contains the version of the service that should be used. And finally in order to use this service from the client using SO-Aware configuration, we need to create the proxy in the following way:
<serviceRepository url="http://localhost/soaware/ServiceRepository.svc"> <services> <service name="ref: People Finder(1.0)" type="Tellago.ServiceModel.Governance.SDK.PeopleFinderService, PeopleFinderService" /> </services> </serviceRepository>
So in this post, we have seen how to set up our first service in SO-Aware and then how to use this configuration from the service and the client.
var resolver = new ConfigurationResolver(new Uri("http://localhost/soaware/ServiceRepository.svc")); var binding = resolver.ResolveBinding("basicHttp"); var endpoint = resolver.ResolveEndpoint("People Finder(1.0)", "WSHttpBinding_IPeopleFinderService"); //here is our new way of creating the proxy. var proxy = new PeopleFinderServiceClient(binding, endpoint); //now we can use the proxy. proxy.CallMyOperation();