Its the beginning of day three of the Indigo Ascend training and here I am writing a review of day one. All the attendees had a pretty strong background in distributed computing technology and were familiar with recent developers in web-services technology.

The presenter for the training was William Tay whose blog I have linked to before. He flew down from Singapore to deliver the content. Most of the first day was spent talking about the whats and the whys of Indigo and looking at the overall architecture along with a few practical demonstrations of how it all hangs together.

We also worked on a number of lab exercises so we could get hands on with the technology. From what I can tell the labs were put together by the guys at Thinktecture, but unfortunately they were based on some relatively old CTP bits so things have moved on quite a bit since then.

The good thing is that by the time I got back to the hotel on Wednesday night my new laptop had arrived and I was able to install the latest bits and apply some of the things that we had been shown in the class. I’ve already posted up about how to build a proxy by hand in the past so I thought I would take the time to describe the 101 of setting up a service to listen via HTTP (not necessarily IIS).

The 1–2–3 of Service Building

The first thing we need is a container to put our projects in, in this case I am creating a HelloWorld solution where I will create the projects needed to get some basic comms going.

CreateHelloWorldSolution

Once the solution is created you just need to create a console application to put the service hosting code in. This is one of the nice things about Indigo, you can host from pretty much anywhere like you can with .NET Remoting, but you can also be standards compliant at the same time.

CreateHelloWorldServiceProject

Once you have the console application created with need to define the contract that our web-service will conform to, we do this by creating an interface like the one below.

CreateIHelloWorldServiceInterface

The interface is only the first part of the process. Once the .NET interface is created attributes defined in the System.ServiceModel assembly (and namespace) need to be applied to the interface. The two attributes that we are interested in are ServiceContractAttribute and OperationContractAttribute. These attributes map closely to the concepts defined in the WSDL 1.1 submission (services and operations).

ApplyServiceOperationAttributes

Both ServiceContract and OperationContract have constructor and named parameters that allow you to shape the format of the meta-data that is ultimately used to generate things like the WSDL. Personally I think you will need to do this all the time because ISomething service and operation names don’t look that great in WSDL – but for simplicity in this post I’ll just keep them with the default values.

Obviously we need to implement the interface so that the web-service can do something. The nice thing about this is that no special attributes are required on the implementation – the hosting system pulls down the service and operation information directly from the interfaces that a class implements.

While I am on the subject it is actually possible to attribute the service implementation directly and host it – but all the cool kids are using contract first with interfaces.

ImplementHelloWorldService

Once a service is defined and implemented you can use the ServiceHost<T> class to host it inside your own stand-alone application. Its worth noting that at this point we are completely independent of the underlying wire protocols, but as soon as we move to hosting the service we need to be aware of how we are going to get clients connecting to it.

I’m not going to cover how you do this with configuration files in this post, instead I’m opting for the code intensive approach which I have found useful for starting to understand the underlying APIs that ship as part of Indigo – hopefully I’ll get a chance to write a reflective post on the pros and cons of this approach in the brave new world of third party service development.

HostHelloWorldService

In the above code I have instansiated the generic ServiceHost passing in the service implementation class as the type parameter. Once that is done it is wired up to the network by adding an endpoint. An endpoint describes what the service contract is (hence the need to specify IHelloWorldService) to a URI and also describes the nature of the binding. The binding that is being used here is WSProfileBinding; during the Indigo Ascend labs we were actually using earlier CTP bits and this used to be called “BasicProfileBinding” which stumped me for a bit.

Correction: I was looking at this last night, BasicProfileBinding does exist as well and produces service endpoints that conform to WS-BasicProfile 1.0a (from what I can tell), WSProfileBinding produces an endpoint that supports a reasonable level of security.

The binding rolls-up multiple choices that you could make into one logical grouping. The beautiful thing about WSProfileBinding is that it is secure by default so authentication is achieved by SSPI – this is of course configurable but for straight-forward desktop to service connectivity its probably the best choice since it will allow security context to flow without having to prompt the user for credentials.

Now thats written its time to start up the service. In the current bits it seems to take a few seconds for everything to warm up correctly but once the prompt is visible you just throw the web-browser at the URL listed in the endpoint code above. This will bring up a web-page that looks very similar to the ASP.NET page generated when you hit an *.asmx file, although it doesn’t have the tester – but that makes sense in an Indigo world.

ViewServiceInfoPageInIE

At this point you just do what the instructions on the page says and run SVCUTIL.EXE passing in the URL to the web-service (remember to leave the web-service running). Like WSDL.EXE in the current toolset this will generate a client-proxy, but rather than lumping the endpoint and profile binding information into the code itself it produces an additional configuration file which you can paste into your App.config file.

GenerateProxy

The code that is produced is a bit like the manual proxy code that I posted last month, but has a lot more attributes to remove any ambiguity. The screenshot below is only a very small snippet of some of the code.

GeneratedCode

Perhaps the most interesting thing about the the code produced is the configuration file that really spells out what is going to happen at the wire level when the client gets up and running.

VerboseConfigurationFile

Even though we specified WSProfileBinding on the server the SVCUTIL.EXE program has emitted a very verbose configuration file. William mentioned that this may be something they address in the future but for now its useful for sniffing out what is going on. In the configuration file the endpoint element specifies that it uses a “customBinding” and the customBinding element spells out the security, transport, encoding and context flow characteristics.

In this case we aren’t flowing transactions, security is using SSPI (as I mentioned before) and the message is being encrypted and signed. The HTTP protocol won’t use authentication (we have that at the message level) and if a proxy is inplace it will be used – but only if it allows anonymous access.

Now that we have looked at the configuration file its time to jump in and call the service. This is pretty much the same as using the good old web reference.

ClientCode

Now that the code is written its time to rock and roll (provided you remembered to copy the generated code into the client project). I’ve found a few quirks when the debugger is or isn’t attached so you might need to run it a few times to get the result out – if I figure out what it is I’ll post up about it (could be my firewall come to think of it).

Next Up

I’m going to post reviews of the second and final days and hopefully throw in a bit of code to, but I just need time to digest everything that was discussed. We also covered some other things on the first day like callback contracts which are interesting but may end up being useless across firewalls.