Code Tips

Web Services Software Factory (2 of 5)

If you have missed part one of this tutorial, you can find it here. You will need to have completed the first part of the tutorial in order to complete this one. In this part you will create the data contracts for this service, the business entities, and the translators to go between them. Just like with classic web services, your data contracts and business entities are essentially different objects as far as .Net is concerned, so you have to create something to map their properties to one another. To get started, you need to have the project loaded up.

Right click on the MyCryptographyService.model project and select Add –> New Model
Add a new Data Contract Model

Opt to create a new “Data Contract Model”. Fill in the Mode name as CryptographyService.DataContracts and the XML Namespace as https://peteonsoftware.com (or whatever you’d like).
Add a new Data Contract Model

You should now have a blank visual designer canvas. Click on the canvas and then view your Properties window (you can’t right click and get properties). Click in the “Implementation Technology” property and choose “WCF Extension”.
Choosing an Implementation Technology

You also need to choose the Project Mapping table for the contracts. This is the XML document (found by default in ProjectMapping.xml) that tells the WSSF which role each project will play and where to auto generate the code. This file can be edited and changes are not overwritten. Set the Project Mapping Table property to MyCryptographyService.
Set the Project Mapping Table

Your toolbox will give you context sensitive tools depending on what part of the project that you are working on. While building data contracts, you will see the tools shown below. A Data Contract represents your serializable objects. The Data Contract Enumeration represents your serializable enumerations. Primitive Data Type Collections and Data Contract Collections represent collections of .Net Data Types and your own custom contracts respectively. You can choose what form these collections take, but most often, I could recommend List. Fault Contracts are for representing Exceptions and Aggregation is for representing relationships between objects.
Choosing an Implementation Technology

Next you need to drag a “Data Contract Enumeration” out of your toolbox and onto the visual designer. Click the name on the top (most likely DataContractEnum1) and change its name to HashType. Right click on the contract and choose Add–>Value. Add values of MD5 and SHA256 to the enumeration.
Add a value to a Data Contract Enumeration

Drag another Data Contract Enumeration onto the surface and name it EncryptionAlgorithm. Add two values, called DES and Rijndael to the enumeration. When you are finished, your surface should look something like this.
Completed Data Contract Enumerations

Now, drag a “Data Contract” from the toolbox onto the designer. Change its name to HashObject in the same way that you renamed the enumeration. Right click on the contract and select Add–>Primitive Data Type. Name this property “StringToHash”.
Data Contract Add Primitive Data Type

Let’s now take a look at the properties of this Primitive Data Type that you just added. It has a type of System.String and an order of 0. For any future Primitive Data Types you add, you may need to change the data type here. You also need to set the order here, as well. For now, we can accept the defaults.
Primitive Data Type Properties

Now, select the Aggregation tool from the toolbox and click on the HashType enumeration, hold down your mouse button, and drag the connection over to the HashObject. This will create a new member on the contract. Set its order to 1.
Data Contract Enumeration Properties

Your HashObject and HashType should look like this on the designer.
Completed HashObject and HashType

You should also create an EncryptionObject by dragging another “Data Contract” onto the designer and setting a Text member and an EncryptionType member in the exact same manner as you did with the Hash Object. When you are finished, you should have these four entities on your designer.
Completed Data Contracts

Right click on any area of whitespace on the designer and click “Validate”. You should have no errors. If you do, make sure that you properly followed all of the steps in this tutorial.
Validate Data Contracts

Next, right click on some whitespace again and click “Generate Code”.
Generate Data Contract Code

If you inspect your MyCryptographyService.DataContracts project’s “Generated Code” folder you will find that some classes have been generated for you. Keep in mind that whenever you make changes to your data contracts, you must regenerate the code and these classes will be overwritten. Fortunately, these classes are created as partial classes, so you can make another .cs file and extend these contracts if you really need to.
Generated Data Contracts
Generated Data Contract Source Code

Right click on the project MyCryptographyService.BusinessEntities and choose Add–>Class. Name the .cs file CryptographicEntities.cs. Inside this file, we will define all of our business entities that the data contracts model so that they can be used elsewhere in our solution. Normally, you would define each of these in their own file, or group them in some other way, but for the purposes of this tutorial we will put all of the code in this file. Replace all of the contents of CryptographicEntities.cs (except the using statements) with the following code.

namespace MyCryptographyService.BusinessEntities

{

    public enum EncryptionAlgorithm

    {

        DES = 0,

        Rijndael = 1

    }

 

    public enum HashType

    {

        MD5 = 0,

        SHA256 = 1

    }

 

    public class EncryptionObject

    {

        public string Text { get; set; }

        public EncryptionAlgorithm EncryptionAlgorithm { get; set; }

    }

 

    public class HashObject

    {

        public string StringToHash { get; set; }

        public HashType HashType { get; set; }

    }

}

Now, right click on the MyCryptographyService.ServiceImplemenation project and choose “Create Translator”.
Create Translator

In the First Class to map, choose the DataContracts.EncryptionObject. For the Second Class to map, choose the BusinessEntities.EncryptionObject. Name the mapping class “EncryptionObjectTranslator” and set the namespace to MyCryptographyService.ServiceImplementation.
Translator Mapper Generator

Choose the Text Property in each of the boxes and click map. Then click finish. You can’t map the enumerations from this dialog and will have to edit the code manually. As long as you don’t regenerate this translator, you don’t have to worry about overwriting the manual changes. In fact, I recommend doing this once to get your guidelines and maintaining it manually anyway.
Translator Map Properties

Repeat this process for our HashObjects. Name the translator HashObjectTranslator and only use the wizard to map the StringToHash properties. Next, open up the translators and make the code look like the following: (Note, I aliased the namespaces to make them shorter and easier to work with).
HashObjectTranslator:

using System;

using MyCryptographyService.DataContracts;

using MyCryptographyService.BusinessEntities;

 

using Contract = MyCryptographyService.DataContracts;

using Entity = MyCryptographyService.BusinessEntities;

 

namespace MyCryptographyService.ServiceImplementation

{

    public static class HashObjectTranslator

    {

        public static Contract.HashObject TranslateHashObjectToHashObject(

            Entity.HashObject from)

        {

            Contract.HashObject to =

                new Contract.HashObject();

            to.StringToHash = from.StringToHash;

            to.HashType =

                (Contract.HashType)from.HashType;

            return to;

        }

 

        public static Entity.HashObject TranslateHashObjectToHashObject(

            Contract.HashObject from)

        {

            Entity.HashObject to = new Entity.HashObject();

            to.StringToHash = from.StringToHash;

            to.HashType = (Entity.HashType)from.HashType;

            return to;

        }

    }

}

EncryptionObjectTranslator:

using System;

using MyCryptographyService.DataContracts;

using MyCryptographyService.BusinessEntities;

 

using Contract = MyCryptographyService.DataContracts;

using Entity = MyCryptographyService.BusinessEntities;

 

namespace MyCryptographyService.ServiceImplementation

{

    public static class EncryptionObjectTranslator

    {

        public static Contract.EncryptionObject TranslateEncryptionObjectToEncryptionObject(

            Entity.EncryptionObject from)

        {

            Contract.EncryptionObject to =

                new Contract.EncryptionObject();

            to.Text = from.Text;

            to.EncryptionAlgorithm =

                (Contract.EncryptionAlgorithm)from.EncryptionAlgorithm;

            return to;

        }

 

        public static Entity.EncryptionObject TranslateEncryptionObjectToEncryptionObject(

            Contract.EncryptionObject from)

        {

            Entity.EncryptionObject to =

                new Entity.EncryptionObject();

            to.Text = from.Text;

            to.EncryptionAlgorithm =

                (Entity.EncryptionAlgorithm)from.EncryptionAlgorithm;

            return to;

        }

    }

}

That’s it. You should be able to successfully build your project now and you are now ready for Part 3. If you have any problems, please feel free to leave them in the comments and I will try to get back to you as quickly as I can. Next time, we will create and implement our service contracts. Until then.

WCF

Web Services Software Factory (1 of 5)

Note: All links current as of the time of this blog post

This is the first in a series of five tutorial posts on the Web Services Software Factory. The Web Services Software Factory (WSSF) is a product that has come out of the Microsoft Patterns and Practices Group and its goal is to aid you in the mundane tasks that accompany setting up a robust WCF or ASMX service. The outline of the tutorials will be as follows:

Post 1: Download, Install, and Setup our Demo Project
Post 2: Create Data Contracts and Implement Business Entities and Translators
Post 3: Create Service Contracts and Implement the Methods
Post 4: Create Host Contract, Deploy and Test WSDL
Post 5: Generate Proxy, Create Simple Client, Call Service to Test

The original WSSF version had a lot of XML configuration to create contracts. With the version that came out in February (called the Modeling Edition), Microsoft Patterns and Practices added a lot of visual designers and even more code generation to the product. However, that is enough of the prelude, lets get into the example.

First you have to do some downloading and installing. You must first download and install GAX (Guidance Automation Extensions) 1.4. It can be found here. Installation is very simple and you just have to run the installer and accept the defaults to go on.

Next, you have to download the WSSF itself. Go here and download the product. If you are on Vista, you have to run the installer from an elevated command prompt. To do that you merely have to get the command prompt to show up in your start menu (either by searching or because you’ve saved it there as I have) and right click on it. Run As Administrator will be one of your options as shown below. After you have the prompt, execute the installer.
Get Elevated Command Prompt

You will then get the installation wizard and again you can accept the defaults and move on.
Install WSSF

Once you have installed the WSSF, start Visual Studio 2008 and click File–> New –> Project. Then select Guidance Packages, Service Factory: Modeling Edition, and then Model Project. Chose a directory and call the project MyCryptographyService and click OK. Note: we are going to do WCF, so make sure that you target Framework 3.0 at a minimum. I’m going to choose 3.5 just to run the “latest and greatest” 🙂
Create Modeling Edition Project

Rename the MyCryptographyService model project file to MyCryptographyService.model (so we can add a project of that same name later).
Rename Default Model

Right click on the solution and choose Add–> WCF Implementation Projects.
Add WCF Implementation Project Menu

This brings up the Add New Project dialog yet again. Name it MyCryptographyService (this is why we renamed earlier) and click OK.
Adding the new WCF Project

Visual Studio will grind away for a second and when it is done, it will have produced a boatload of projects for you in your solution. You will also notice that the projects that should reference each other already do, helping you along in making sure that you separate your code properly. Build your project and everything should build nicely. It doesn’t do much now, but more will come next time. If you have errors, please make sure that you followed the steps correctly.
Solution Explorer Populated with Projects

Next time we will dig into the designers and begin to implement the entities in our project.

Rant

Y Kant Developers Read?

Bookshelf image from flickr.com/photos/ianturton/2341264331/
I guess there are two major reasons that developers don’t read many books. This is kind of a timely subject for me right now on both fronts.

First, I began a new job at the beginning of last month. My new employer was running a Visual Fox Pro environment and wants to move to a full-blown .Net SOA Architecture. I was brought in to architect that. The team that I have (save one programmer that I recommended and was hired) are all Visual Fox Pro 6 developers who don’t know a stitch of .Net. With the exception of one guy (who I *really* appreciate), none of them seem to be very interested in reading books to find the answers to problems or to learn the gist of C# and ASP.Net.

This was also the case at my last job. With the exception of the guy who I recommended at my new place, no one would read books. They would take them at our insistence and then never read them. Someone once told me that developers read about one technical book a year on average. I couldn’t believe it when I heard it, but I’m starting to wonder if that number isn’t smaller. The first major reason just seems to be laziness and/or apathy.

The second major reason seems to be the driving force behind Jeff Atwood and Joel Spolsky‘s new venture, StackOverflow. According to Joel, “Programmers seem to have stopped reading books. The market for books on programming topics is minuscule compared to the number of working programmers. Instead, they happily program away, using trial-and-error. When they can’t figure something out, they type a question into Google.”

I believe that to certainly be true, and for people who are using new technologies or are on the bleeding edge, trial-and-error is the only way to go. However, if we are talking about anything that is approaching a year old, books certainly exist. My problem with trial-and-error and Google is that you never really *learn* anything. You are kind of limited to your own cleverness.

Advanced books not only teach you new features, they teach you new techniques. If you just trial-and-error, you will only try to figure out the Python way to do your C# code, or the Ruby way to do what you’ve always done in Java. You won’t learn what there is to learn about the new languages and the cultural mindset that comes with them. You could skip reading books and read lots and lots of source code, but I don’t believe a majority of developers are doing that, either.

However, so far we’ve only talked about learning a new programming language or technology. There is no way to effectively trial-and-error the kind of knowledge that you get from books like Code Complete, Pragmatic Programmer, GOF Design Patterns, or Practical Cryptography. How in the world has this style of learning, proven effective for centuries, fallen so far by the wayside? I am not trying to seem terribly elite, but I really read more than an entire technical book per month on average, along with several technical magazines and journals. I directly attribute my success in my field to that fact. Why can’t people see books as an avenue to their greater success?

Fluff

Great Quote From K

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you’re as clever as you can be when you write it, how will you ever debug it?”
     – Brian Kernighan (the K of the essential K&R C book)

Code Tips

Anonymous Types in C# 3.0

For a long time, the var keyword has been the domain of only wholly dynamically typed languages. In fact, some people from the strongly-typed camp have considered the use of var as “hacky”, even though C#-ians have been able to treat everything as an object all along. Granted, it is not exactly the same and there is the whole boxing and unboxing thing to deal with, but I wanted to include full disclosure.

Now however, dynamic languages are all the rage and people are finding good uses for a generic variable type. To harness that power, one of the things done in C# 3.0 was the creation of Anonymous Types. Examine the code below and its output.

var blogPost = new
{
    Name = "Anonymous Types in C# 3.0",
    Author = "Pete Shearer",
    Category = "Code Tips"
}; 

Console.WriteLine(blogPost.Name);
Console.WriteLine(blogPost.Author);
Console.WriteLine(blogPost.Category);

Anonymous Types Output

By declaring my variable blogPost with the var keyword, I have created a dynamic variable. Now, after the new keyword and inside the curly braces, I declare a few properties and set their values. Behind the scenes, the compiler has declared a new object, given it a temporary name, and set the values in “traditional” fashion. It is even smart enough that if I declared another var with that definition, it wouldn’t redefine the anonymous type.

Within the anonymous type, the object remains strongly typed. Consider the following alteration to the code:

var blogPost = new
{
    Name = "Anonymous Types in C# 3.0",
    Author = "Pete Shearer",
    Category = "Code Tips",
    Date = new DateTime(2008, 3, 27)
}; 

Console.WriteLine(blogPost.Date.GetType());

Anonymous Types Output 2

The compiler inferred the type from the object placed into it. I know that I said new DateTime there, but it would have worked for any type that I put into that property. This new feature certainly affords developers a new level of flexibility. Enjoy.