Archive for November 2007
In my previous posting I mentioned, that even small samples and code snippets eventually end up in production code. Today I want to elaborate further on this.
By its nature sample code has to be simple. A code sample is intended to showcase a specific feature of a framework. When possible, isolated from other features of the framework for the sake of simplicity. This is often done by not taking care of security, performance and maintenance.
On the other hand we have so called "best practices." Best practice comes as a response on problems of customers, blindly copying-and-pasting code samples into their production code. This is, of course, not the only intention behind best practices, they also show how to combine usage of different parts of a framework or frameworks together. And I won’t blame copy-pasting developers just because copy-paste is the most productive development approach to meet functional requirements on time.
So, why does that happen? Because of poorly designed frameworks, of course. Why else? Brad Abrams and Krzysztof Cwalina in their book "Framework Design Guidelines" define the term "pit of success" for a situation when the simplest subset of an API leads developers to best results. Best results here mean not only quick implementation of functional requirements, but non-functional as well. I, as a developer, want to get good performance and solid security when using default configurations and simplest overloads of methods and constructors. As opposite, it should be really non-trivial to screw everything up.
So, if a framework satisfies the "pit of success" criteria, it probably does right things with less code. As a result, code samples become production-ready, and best practices can concentrate on the more complex and interesting job of integrating different pieces together and building a whole solution for a specific problem.
Microsoft has significantly improved quality of its products during the last few years. This allowed Microsoft to ship yet beta versions of their products under the "GoLive" license, which permits customers to use beta versions in production. Until we work with perfectly designed frameworks only, I would like to encourage both framework developers and communities to create more production-ready code samples. Improve quality of your code samples and make them go live!
I was recently hunting down an issue with accessing a WSE 3.0 web service hosted in a custom application. Symptoms are very familiar: a client can access the service only using exactly the same URL as was used to set up a listener on the server; i.e. if I set up a listener on "soap.tcp://localhost/my-service/", I can not access it neither on "soap.tcp://127.0.0.1/my-service/" nor on "soap.tcp://localhost:8081/my-service/" nor even on "soap.tcp://machinename/my-service/", which all obviously point to the same location.
In this small article I’ll try to explain why does this issue happen and will provide a solution.
.NET supported web services development starting from its very first version. Web services were nothing but an extension to ASP.NET and therefore relied on much of ASP.NET infrastructure. Including hosting. To host an ASP.NET web service all we need was to put an ASMX file defining the service on the web server (Internet Information Services for instance) and hook the ASP.NET pipeline to handle it. The only transport, supported out of the box, was obviously HTTP. And we didn’t care much, while relying on ASP.NET and a web server. Clients were invoking the service with any URL as long as it pointed to the hosting machine and the requested ASMX file on its web server.
Later came Web Services Enhancements (WSE) which allowed communicating true WS-* protocols and custom hosting of web services. More power brings more complexity. I case of custom hosting, we now can control (meaning have to think about) which network interfaces the service should listen on. Moreover, on the same network interface and port multiple web services can be identified by their unique names. To call such a service a simple URL is not enough anymore.
WS-Addressing specification addresses exactly this issue, providing the endpoint reference element (EPR). EPR differentiates service identification and service location storing them in its "address" and "via" elements respectively. When initialized, a listener uses the "via" element to bind required networking sockets, and the "address" element to identify a service when it receives a message on one of its bound network interfaces.
In the simplest case—which is illustrated in almost all samples and tutorials—ERP will be created with only one URL for both "address" and "via" elements. Obviously, a different URL on the server and on the client leads to the abovementioned issue, because the server compares the "address" elements to identify the requested service.
A far more better approach would be to use a Uniform Resource Name (URN, e.g. "urn:my-services:one-of-them") as the "address" of the service separate from its "via". "Via" on the server could be, for example, "soap.tcp://0.0.0.0/" for listening on all available network interfaces on port 8081 (default port for soap.tcp transport). The client on its side could use as "via" in this case any URL, that points to the port 8081 on the server.
Understanding WS-* specifications, such as WS-Addressing, is very important for developing connected systems using WSE and/or WCF because WS-* is a native object model for both frameworks. Unfortunately, we developers under pressure of time tend to blindly copy-and-paste samples and tutorials into production code, leaving understanding of concepts for a better time. The only thing we all can do about it is to try to make sample code as much as possible appropriate for production. But it’s a topic for another article
Vittorio Bertocci did a demo on developing a Security Token Service with the new ADFS "2" Identity Framework at TechEd in Barcelona. I’ve not attended Vittorio’s demo, although I was on TechEd (there are so many great talks and discussions at the same time, but it is another topic). Fortunately, Vittorio has posted the first part of the demo on his blog.
I built an STS myself with pure WCF some time ago when I was playing with CardSpace, so I was really impressed by the new framework. Although I see some ways of improvement, nonetheless the Identity Framework is a huge leap toward the implementation of user-centric digital identity.
Are you building yet another social network or just a web 2.0 application, and want your users to register? Consider leveraging the benefits of information cards and the Identity Framework, make the life a bit easier for your users!
My blog was dead for a while because I didn’t write for some reasons. First, I’ve changed my job and it has made me change the focus of my interests in technology (not so radically, I hope). Second, my blog was hosted by my former employer, who was undergoing a kind of IT reorganization. As a result at the time of writing the blog renders the famous ASP.NET Yellow Screen of Death
My current job is building healthcare line of business software products in a team of 30+ people for one particular midsize ISV in Germany. As a result I’m going to write in this new blog about all the aspects of my work: technologies, software, people, etc.
The good news is that now I have finally decided for a blog hosting solution, which is the Windows Live platform (Spaces + Admin Center + SkyDrive). I’ve imported almost all of my old blog posts here and now evaluate the new platform. At first glance it looks not that bad as I thought, I even figured out how to hide all those "social" features of Live Spaces What I still lack for, is a real integration of Custom Domains (renamed to Admin Center now) and Spaces. I mean not a simple redirection but a true URL rewriting.
So, let’s blog again!