ASP.NET MVC Making Web Development Fun Again

I want to thank Scott Guthrie and Scott Hanselman and the whole ASP.NET MVC team for making web development fun again.

The simplicity of Rails, the power of .NET, and so much more. I've been reading the posts and watching some of the screencasts but had not yet tried it for real. That all changed over the weekend while working my latest pet project which I hope to reveal sometime soon. I decided to put MVC Preview 4 to the test. I was not disappointed.

I mean, who could not fall in love with the elegant simplicity of this view?

<tr>
  <td>Current password:</td>
  <td><%= Html.Password("currentPassword") %></td>
</
tr>
<
tr>
  <td>New password:</td>
  <td><%= Html.Password("newPassword") %></td>
</
tr>
<
tr>
  <td>Confirm new password:</td>
  <td><%= Html.Password("confirmPassword") %></td>
</
tr>
<
tr>
  <td></td>
  <td><input type="submit" value="Change Password" /></td>
</
tr>

Handled by this controller:

[Authorize]
public ActionResult ChangePassword(string currentPassword, string newPassword, string confirmPassword)
{

    ViewData["Title"] = "Change Password";
    ViewData["PasswordLength"] = Provider.MinRequiredPasswordLength;

    // Non-POST requests should just display the ChangePassword form
    if (Request.HttpMethod != "POST")
    {
        return View();
    }

    // Basic parameter validation
    List<string> errors = new List<string>();

    if (String.IsNullOrEmpty(currentPassword))
    {
        errors.Add("You must specify a current password.");
    }
    if (newPassword == null || newPassword.Length < Provider.MinRequiredPasswordLength)
    {
        errors.Add(String.Format(CultureInfo.InvariantCulture,
                    "You must specify a new password of {0} or more characters.",
                    Provider.MinRequiredPasswordLength));
    }
    if (!String.Equals(newPassword, confirmPassword, StringComparison.Ordinal))
    {
        errors.Add("The new password and confirmation password do not match.");
    }

    if (errors.Count == 0)
    {

        // Attempt to change password
        MembershipUser currentUser = Provider.GetUser(User.Identity.Name, true /* userIsOnline */);
        bool changeSuccessful = false;
        try
        {
            changeSuccessful = currentUser.ChangePassword(currentPassword, newPassword);
        }
        catch
        {
            // An exception is thrown if the new password does not meet the provider's requirements
        }

        if (changeSuccessful)
        {
            return RedirectToAction("ChangePasswordSuccess");
        }
        else
        {
            errors.Add("The current password is incorrect or the new password is invalid.");
        }
    }

    // If we got this far, something failed, redisplay form
    ViewData["errors"] = errors;
    return View();
}

Yes, you say, but what about all my high powered controls from XYZ Controls Company? Do they really make your life that much easier? Is HTML so hard? Have you looked at your ViewState lately? Yikes! Certainly there are tradeoffs, but you can bet that controls are on their way. Where Microsoft stack developers go, the control vendors soon follow.

Give me clean HTML with CSS style and controllers that support TDD in the most straightforward manner I've ever seen, sprinkle in some convention over configuration jazz from Ruby on Rails, and I'm a happy web developer again after having spent the last four and a half years avoiding ASP.NET while writing back end data and content analysis systems.

ASP.NET never looked better!

 

Some Things are True Whether They are True or Not

I get a lot of forward email from friends and relatives. I've never felt compelled to do anything with any of them until, bored this evening, I read this one from my father-in-law. I don't know if any of these stories are true or not, but whether they are or aren't, they are. In a time when America seems to be taking much criticism from within and without, it's good to have reminders like these.

When in England, at a fairly large conference, Colin Powell was asked by the Archbishop of Canterbury if our plans for Iraq were just an example of empire building by George Bush. He answered by saying, 'Over the years, the United States has sent many of its fine young men and women into great peril to fight for freedom beyond our borders. The only amount of land we have ever asked for in return is enough to bury those that did not return.'

There was a conference in France where a number of international engineers were taking part, including French and American. During a break, one of the French engineers came back into the room saying 'Have you heard the latest dumb stunt Bush has done? He has sent an aircraft carrier to Indonesia to help the tsunami victims. What does he intended to do, bomb them?' A Boeing engineer stood up and replied quietly. 'Our carriers have three hospitals on board that can treat several hundred people; they are nuclear powered and can supply emergency electrical power to shore facilities; they have three cafeterias with the capacity to feed 3,000 people three meals a day, they can produce several thousand gallons of fresh water from sea water each day, and they carry half a dozen helicopters for use in transporting victims and injured to and from their flight deck. We have eleven such ships, how many does FRANCE HAVE?'

A U.S. Navy Admiral was attending a naval conference that included Admirals from the U.S., English, Canadian, Australian and French Navies. At a cocktail reception, he found himself standing with a large group of Officers that included personnel from most of those countries. Everyone was chatting away in English as they sipped their drinks but a French admiral suddenly complained that, whereas Europeans learn many languages, Americans learn only English. He then asked, 'Why is it that we always have to speak English in these conferences rather than speaking French?' Without hesitating, the American Admiral replied "maybe it's because the Brits, Canadians, Aussies and Americans arranged it so you wouldn't have to speak German.'

An elderly American gentleman of 83, arrived in Paris by plane. At French Customs, he took a few minutes to locate his passport in his carry on. 'You have been to France before, monsieur?' the customs officer asked sarcastically. The man admitted that he had been to France previously. 'Then you should know enough to have your passport ready.' The American said, 'The last time I was here, I didn't have to show it. 'Impossible. Americans always have to show your passports on arrival in France !' The American senior gave the Frenchman a long hard look. Then he quietly explained, 'Well, when I came ashore at Omaha Beach on D-Day in 1944 to help liberate this country, I couldn't find a single Frenchmen to show a passport to.'

Serenity and Leukemia: An Angel's Battle with Cancer

One of my very best friends, Phil Burns, whom I love like a brother, called me Friday afternoon. But it wasn't him.

It was his phone but I did not recognize the voice on the phone. The voice belonged to a woman whom I assume was a hospital emergency room employee. She informed me that Phil's wife Adria was boarding an ambulance with their 22 month old daughter Serenity to be transported from the American Fork Hospital to the Primary Childrens Hospital in Salt Lake City. I asked what was wrong and she told me that Serenity was very sick and may have leukemia.

I was stunned. I told her to let Phil know I'd be in touch very soon or to call me when he was able with more news. I cut short a business lunch and walked back to the office from the food court and let my boss know that I'd be gone the rest of the afternoon. On the way home, Phil called me and was very upset. He told me some of the story that you can find on his blog.

Between sobs of grief and fear, Phil begain to tell me the story. His tiny little angel named Serenity, not yet two years old, was on her way to the best childrens hospital in the intermountain west. A helicopter was on standby in case her breathing became more shallow. Phil was on his way home to pick up some things for a hospital stay that he was told would be at least three or more days. I told him I'd meet him there.

Serenity is the very definition of purity and beauty. Here large brown eyes, which you can see here on a site that a friend has put together, can melt your heart and make you want to do anything you can to alleviate her suffering.

The good news is that her prognosis is very hopeful but she will have to go through a lot to get there. She will get through it with a mountain of love and sea of patience from her parents and family and friends. But it will take one more thing: a Greengotts vault full of gold. The Burns family has no health insurance. And the hospital calls leukemia babies "Million Dollar Babies." The Burns family will need every bit of assistance we can give them. You and I can help. A donation account has been setup. Please open your wallet as far as this bright little angel can open your heart. If you have the courage to look into her eyes and wonder what the rest of her life holds in store, opening your wallet to help with the bills will be something you cannot avoid.

Windows Form Talks to Windows Service via WCF without Config File

I am fascinated with Windows Communication Foundation (WCF) but the configuration files can be cumbersome. Until now I haven't had the time to investigate programmatic configuration of WCF, but I may be involved in a project soon in which WCF would be useful but where configuration files would present an unnecessary complication to the end user. So I've spent some time researching and experimenting. To my happy surprise, WCF is easily configured programmatically. A little research has resulted in a simple Windows Forms application talking to a Windows Service via WCF while both client and server use a common class library that defines the service contract and data transfer objects. I'll give you a brief overview and then you can download the solution here.

First let me give credit where credit is due. I could not have figured out all of this stuff without the great help of Juval Lowy and his book Programming WCF Services. I highly recommend the book. I also took advantage of some of the samples published on his http://www.idesign.net/ web site. If you need help with your WCF work, I urge you to contact them.

You download the entire solution at the bottom of this entry, so I'm not going to push all the code into the text here, but I'll try to cover the highlights.

Framework/Architecture
The architecture of this little test application is simple.

  • MyWcfService - (server) A Windows service application
  • MyWcfMon - (client) A Windows Forms application with a simplistic test
  • MyWcfLib - A class library defining the service contract used by client and server

MyWcfLib
Since I like the "contract first" approach, let's begin with the interface and data transfer objects shared by client and server. This is a very simple piece of code but sufficient to illustrate the principles involved (see IMyWcfServiceControl.cs).

[ServiceContract]
public interface IMyWcfServiceControl
{
    [OperationContract]
    MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command);
}

[DataContract]
public class MyWcfServiceCommand
{
    [DataMember]
    public string Command { get; set; }
}

[DataContract]
public class MyWcfServiceResponse
{
    [DataMember]
    public string Response { get; set; }
}

As you can see, we have a simple service contract with a single operation and a simple command object taken and response object returned.

You'll also notice an Extensions.cs file in the MyWcfLib project. These are a few of my favorite extensions I've written lately. I find them very useful but they are not terribly relevant to this project. You can take a look at them later in the source download.

MyWcfService
I won't bore you with the details of the Windows service code, though I do encourage you to download the code and give it a look. I've blogged about this before but it's worth metioning, if only for the keyword exposure. The service code allows you to debug the service as a console application and then compile in "Release" and deploy/install as a real Windows service. A handy little chunk of code.

The primary area of interest in the service is the declaration of the WCF ServiceHost and how it is configured in code. In the following lines of code found in the MyWcfService.cs file in the project, we create a WCF host listening on a port configured using the m_port value, requiring Windows authentication and using encryption and message signing on the transport layer. Fast but highly secure.

Uri tcpBaseAddress = new Uri(string.Format("net.tcp://localhost:{0}/", m_port));
serviceHost = new ServiceHost(typeof(MyWcfServer), tcpBaseAddress);

NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.Transport, false);
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;

serviceHost.AddServiceEndpoint(typeof(IMyWcfServiceControl), tcpBinding,
    string.Format("net.tcp://localhost:{0}/MyWcfServiceControl", m_port));

//this is the default but good to know
serviceHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseWindowsGroups;

serviceHost.Open();

That's it. We're now configured. Not so hard. Not really any more difficult than raw .NET remoting configuration. In fact, probably easier.

Of course, the Stop method on the ServiceRunner class executes the Close method on the service host.

Now to the implementation of the IMyWcfServiceControl interface in the MyWcfServer.cs file:

internal class MyWcfServer : IMyWcfServiceControl
{
    [PrincipalPermission(SecurityAction.Demand, Role = @"nbdev2\allwcfgroup")]
    [PrincipalPermission(SecurityAction.Demand, Role = @"nbdev2\mywcfgroup")]
    public MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command)
    {
        MyWcfServiceResponse response = null;
        if (IsAuthorized())
        {
            response = new MyWcfServiceResponse()
            {
                Response = command.Command + " response " + DateTime.Now.ToLongTimeString()
            };
        }
        else
        {
            response = new MyWcfServiceResponse()
            {
                Response = "Error: user not authorized"
            };
        }
        return response;
    }

    bool IsAuthorized()
    {
        //The PrincipalPermission attributes are an OR proposition.
        //The following enforces the AND requirement.
        IPrincipal p = Thread.CurrentPrincipal;
        if (p.IsInRole(@"nbdev2\allwcfgroup") && p.IsInRole(@"nbdev2\mywcfgroup"))
            return true;
        else
            return false;
    }
}

Note that we have two layers of security authorization employed here. (Authentication has already been handled automatically for us.) First we have two PrincipalPermission attributes that demand that the user be in one of two groups. But in fact, our invented requirement here is that the user belong to both groups. Don't ask me why. It's a demo.

So the IsAuthorized method is called and there we examine the Thread.CurrentPrincipal to learn if the requirement is met. This was a revelation to me. I did not know that the thread handling the single call to the WCF service would be running under the calling user context. A very good thing to know. Note to self...

MyWcfMon
Now to the client. It's simple really, and you could probably find an even more clever way to write it, but this might help you get started. You will find in the source a file called MyWcfServiceProxy.cs where the following code lives in the MyWcfServiceProxy class:

internal MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command)
{
    NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.Transport, false);
    tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
    tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;

    EndpointAddress endpointAddress =
        new EndpointAddress(string.Format("net.tcp://{0}:{1}/MyWcfServiceControl", m_server, m_port));
    
    MyWcfServiceControlClient proxy = new MyWcfServiceControlClient(tcpBinding, endpointAddress);

    //Note: current user credentials are used unless we use runtime provided credentials like this
    NetworkCredential credentials = new NetworkCredential(m_userName, m_password);
    if (m_domain != null) credentials = new NetworkCredential(m_userName, m_password, m_domain);
    proxy.ClientCredentials.Windows.ClientCredential = credentials;
    
    MyWcfServiceResponse response = proxy.ExecuteCommand(command);
    
    //if proxy is in Faulted state, Close throws CommunicationObjectFaultedException
    if (proxy.State != CommunicationState.Faulted) proxy.Close();

    return response;
}

class MyWcfServiceControlClient : ClientBase<IMyWcfServiceControl>, IMyWcfServiceControl
{
    public MyWcfServiceControlClient(Binding binding, EndpointAddress address) : base(binding, address) { }
    public MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command)
    {
        MyWcfServiceResponse response = null;
        try
        {
            response = Channel.ExecuteCommand(command);
        }
        catch (SecurityNegotiationException ne)
        {
            response = new MyWcfServiceResponse() { Response = ne.Message };
        }
        catch (SecurityAccessDeniedException ae)
        {
            response = new MyWcfServiceResponse() { Response = ae.Message };
        }
        return response;
    }
}

The WCF client is easily configured programmatically as you can see. Create a Binding, an EndpointAddress, a NetworkCredential if you want to, and then call the service. The private MyWcfServiceControlClient class just makes it a little easier to isolate the configuration code in the code above it.

So now, we have a simple Form that does this:

string userName = txtUserName.Text;
string password = txtPassword.Text;
MyWcfServiceProxy sp = new MyWcfServiceProxy("localhost", 8239, userName, password, null);
MyWcfServiceCommand command = new MyWcfServiceCommand()
{
    Command = "Hello world."
};
MyWcfServiceResponse response = sp.ExecuteCommand(command);
lblTest.Text = response.Response;

With this little framework, you can extend the command and response classes and build pretty much anything you want between your Windows Forms application and your Windows service with the comfort of secure, encrypted and signed communication between the two on the port of your choice.

If you find this useful, I'd love to hear about it. The code can be found here MyWcfService.zip (31.6KB) under the MIT license. Enjoy! 

ConfigurationSection Lesson on ConfigurationErrorsException

I was playing around with some old code in which I had a custom ConfigurationSection (see code below). I had an attribute in the configuration section that I wanted to change from an Int32 to a Double. Seems a simple change. Just a little refactoring of the ConfigurationElement class changing the "int" declaration to "double" and it compiles. But kablam! It does not run but throws a nasty System.Configuration.ConfigurationErrorsException with this explanation:

The default value for the property 'size' has different type than the one of the property itself.

Huh? Turns out the type inference on the DefaultValue property in the ConfigurationProperty attribute is rather picky. Here's what I had originally:

[ConfigurationProperty("size", DefaultValue = 1, IsKey = false, IsRequired = true)]
public int Size
{
    get
    { return (int)this["size"]; }
    set
    { this["size"] = value.ToString(); }
}

And here's what I changed it to thinking it would run just fine:

[ConfigurationProperty("size", DefaultValue = 1, IsKey = false, IsRequired = true)]
public double Size
{
    get
    { return (double)this["size"]; }
    set
    { this["size"] = value.ToString(); }
}

Just because the above code compiled, does not mean it will work correctly. So here's what really worked:

[ConfigurationProperty("size", DefaultValue = 1.0, IsKey = false, IsRequired = true)]
public double Size
{
    get
    { return (double)this["size"]; }
    set
    { this["size"] = value.ToString(); }
}

Small but important lesson to learn. Here's the whole code and following it the snippet from the config file in case this is the first time you've written a custom config handler.

using System;
using System.Collections;
using System.Text;
using System.Configuration;
using System.Xml;

namespace MyConfigBox
{
    public class SizeLimitConfigurationSection : ConfigurationSection
    {
        [ConfigurationProperty("hostSize")]
        public HostSizeConfigCollection HostSize
        {
            get
            {
                return ((HostSizeConfigCollection)(base["hostSize"]));
            }
        }
    }

    [ConfigurationCollectionAttribute(typeof(HostSizeConfigElement))]
    public class HostSizeConfigCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new HostSizeConfigElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((HostSizeConfigElement)(element)).Name;
        }

        public void Add(HostSizeConfigElement element)
        {
            this.BaseAdd(element);
        }

        public void Remove(string key)
        {
            this.BaseRemove(key);
        }

        public void Clear()
        {
            this.BaseClear();
        }

        public HostSizeConfigElement this[int idx]
        {
            get { return (HostSizeConfigElement)this[idx]; }
        }
    }

    public class HostSizeConfigElement : ConfigurationElement
    {
        public HostSizeConfigElement() { }
        public HostSizeConfigElement(string name, double size)
        {
            this.Name = name;
            this.Size = size;
        }

        [ConfigurationProperty("name", DefaultValue = "_", IsKey=true, IsRequired = true)]
        [StringValidator(InvalidCharacters = "~!@#$%^&()[]{}/;'\"|\\", MinLength = 1, MaxLength = 260)]
        public string Name
        {
            get
            { return (string)this["name"]; }
            set
            { this["name"] = value; }
        }

        [ConfigurationProperty("size", DefaultValue = 1.0, IsKey = false, IsRequired = true)]
        public double Size
        {
            get
            { return (double)this["size"]; }
            set
            { this["size"] = value.ToString(); }
        }
    }
}

And now here's the config file (some items removed to clean it up a bit and just show the relevant parts):

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="sizeLimits" type="MyConfigBox.SizeLimitConfigurationSection, MyConfigBox" />
    </configSections>
    <appSettings/>
    <connectionStrings/>

    <sizeLimits>
        <hostSize>
            <add name="netbrick.net" size="17.5" />
            <add name="duovia.com" size="42.4" />
        </hostSize>
    </sizeLimits>

</configuration>

And here's an example of how to use the custom config handler in code:

SizeLimitConfigurationSection config =
   (SizeLimitConfigurationSection)(System.Configuration.ConfigurationManager.GetSection("sizeLimits"));
//now use config to get at the items in the hostSize collection of HostSizeConfigElement objects

So watch those attribute values because sometimes the compiler won't.

Heap, Stack, Reference Types and Value Types in .NET

When something works well on its own with a high level of reliability, we tend to take it for granted and forget about the mechanics of how it works. We turn the key of our car and expect the engine to fire up. No thought is given to the inner workings of the internal combustion engine.

We write .NET code and expect the CLR and its garbage collector to manage memory for us without having to think much about value types, reference types, the stack and the heap. We just write code that works and thank our lucky stars that we've seen the last of malloc. Sure we have to dispose of some objects that reference system or outside resources manually but that's simple work.

But sometimes it's fun to look under the hood. And who knows, it might show up on a test.

So what is the heap and the stack and what is the difference between a reference type and a value type and what do they have to do with the stack and the heap and garbage collection?

You're right. I'm about to tell you. Now I'm not a compiler or CLR guru and this is not a graduate level CS class. This is a blog post, so we'll try to keep it real. There are far greater explainations that go into much more detail out there on the web and in texts. I hope this post will serve as a summary reminder of these concepts and help us understand the engine under the hood a bit better. And remember, this post is based on what I know, so if I'm wrong about something here, please feel free to correct me.

What is the Stack?
The Stack is essentially a LIFO (last in, first out) execution stream for a given thread (each thread gets its own Stack) with the most recently called method on the top containing parameters, stack allocated value types (more on that later), and references or pointers to data items in the Heap. The CLR using the JIT compiler manages what goes on the Stack. When a method returns or fires an unhandled exception, that top item on the Stack is removed and control is returned to the next item on the Stack. Sometimes you will see the Stack referred to as the "call stack."

What is the Heap?
The Heap's purpose is to hold information. The Heap is like a filing cabinet where data is stored. While the Stack is only accessed by the CLR in a LIFO fashion, the Heap can be accessed without constraint. The Heap contains the data you generally think of as variables or objects that are reference types. When we're done with things in the Heap, they have to be cleaned up to make room for other things. That's the job of the garbage collector.

What is a Value Type?
A value type is an object that is derived implicitly from the System.ValueType which overrides the System.Object virtual methods more appropriate to value types. Value types fall into to main categories:

Structs
Structs fall into these categories:
  • numeric types
    - integral types (byte, char, short, int, long, sbyte, ushort, uint, ulong)
    - floating-point types (double, float)
    - decimal
  • boolean
  • user defined structs
 
 Enumerations
 Enumerations are a set of named constants with an underlying type which can be any integral type except System.Char.

Value types are allocated on the Stack or allocated inline in a structure. This means that value types are almost always stored in the execution or call stack memory. When they're used like an object, they're wrapped up to look like a reference type and placed on the Heap. This is called boxing. Bringing the object back into use on the Stack as a value type is called unboxing.

The most important thing to remember about value types is that the assignment of one value type to another results in the data being copied. For example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackHeap
{
    class Program
    {
        static void Main(string[] args)
        {
            MyData me = new MyData();
            me.Age = 42;
            me.Name = "Sam";
            me.Relationship = "married";

            MyData her = me;
            her.Age = 44;
            her.Name = "Mary";

            Console.WriteLine("I am {0} years old. My name is {1}.", me.Age, me.Name);
            Console.WriteLine("She is {0} years old. Her name is {1}.", her.Age, her.Name);
            Console.WriteLine("I am {0} to her. She is {1} to me.", me.Relationship, her.Relationship);

            Console.ReadLine();
        }
    }

    public struct MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }
}

Output
 I am 42 years old. My name is Sam.
 She is 44 years old. Her name is Mary.
 I am married to her. She is married to me.

The assignment of the Age value applies only to the copy of the original. It is a value type.

Now consider the output if we make MyData a reference type by changing it to a class.

    public class MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }

Output
 I am 44 years old. My name is Mary.
 She is 44 years old. Her name is Mary.
 I am married to her. She is married to me.

The assignment of the Age and Name values apply to both objects now because the variable refers to or points to the object created with the "new MyData()" call.

The same behavior can be observed in using value types and reference types as parameters. Consider this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackHeap
{
    class Program
    {
        static void Main(string[] args)
        {
            MyData me = new MyData();
            me.Age = 42;
            me.Name = "Sam";
            me.Relationship = "married";

            MyData her = me;
            her.Age = 44;
            her.Name = "Mary";

            ModifySomeData(me, ref her);

            Console.WriteLine("I am {0} years old. My name is {1}.", me.Age, me.Name);
            Console.WriteLine("She is {0} years old. Her name is {1}.", her.Age, her.Name);
            Console.WriteLine("I am {0} to her. She is {1} to me.", me.Relationship, her.Relationship);

            Console.ReadLine();
        }

        private static void ModifySomeData(MyData me, ref MyData her)
        {
            me.Age = 50;
            her.Age = 50;
            Console.WriteLine("\nMy age changed to {0} as value type parameter.", me.Age);
            Console.WriteLine("Her age changed to {0} as value type parameter passed by ref.\n", me.Age);
        }
    }

    public struct MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }
}

Output
 My age changed to 50 as value type parameter.
 Her age changed to 50 as value type parameter passed by ref.
 
 I am 42 years old. My name is Sam.
 She is 50 years old. Her name is Mary.
 I am married to her. She is married to me.

Notice that her.Age changed permanently and me.Age changed only in the "copy" in the ModifySomeData method because it was not passed as a "by ref" parameter. Now what happens to the output if we change the MyData to a class rather than a struct? Here's the output if we make MyData a reference type by making it a class:

    public class MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }

Output
 My age changed to 50 as value type parameter.
 Her age changed to 50 as value type parameter passed by ref.
 
 I am 50 years old. My name is Mary.
 She is 50 years old. Her name is Mary.
 I am married to her. She is married to me.
 

So what happened when we passed a value type "by ref" in the example above? It was boxed into a reference type. And when we changed MyData into a class, the parameters are passed "by ref" regardless of whether the "ref" keyword is used. This is an important distinction to learn when dealing with parameter values.


What is a Reference Type?
Reference types can be a class, interface or delegate. All classes are ultimately derived from System.Object. Interfaces and delegates are special reference types. Exactly what they are and how they are used is a subject for another day. There are two built in reference types: object and string. These types are "native" to the CLR and do not require a "class definition" in code. All other reference types are defined in existing framework assemblies, third party assemblies or in your own code.

When you create an instance of a reference type or pass that instance as a parameter, a pointer is placed in the call Stack that references the object in the Heap. While value types live in the call Stack and are cleaned up with the removal of their associated execution call, the data on the Heap must be cleaned up by the garbage collector (GC).

What is the GC?
The garbage collector in the .NET CLR is the intelligent mechanism that deals with data on the Heap for which there is no reference or rather no existing pointer in the call Stack. It scans the Stack from time to time to determine if an object in the Heap is referenced. If the object is no longer referenced, it removes the object from the Heap returning that memory space to the runtime and eventually to the system.

The GC uses a "generations" approach to improve the speed with which garbage collection is done. The reason this is required is that while garbage collection is done (the traversing of the call Stack and iteration through the Heap), nothing else can be done. In other words, all processing threads are halted while garbage collection is performed.

The GC marks each object in the Heap with a generation value: 0, 1 or 2. The reason for this is that objects that make it through two garbage collection passes are likely to be objects that will live a long time, such as a Windows.Form object. On the other hand, short lived objects such as a local string literal will generally not survive one garbage collection pass. By marking objects with a generation value, the GC can prioritize its work. For example, if sufficient memory is recovered by examining objects with the generation value of zero, then further garbage collection is not required and processing may continue. This way you get a good balance between memory use and performance.

Summary
That's about all I have to say on this subject for now. I'm sure that virtual forests have been consumed in addressing these topics, but writing this up has been a good exercise for me. If you find mistakes, please let me know but go easy on me. :)

Seven Days Past the Layoff

A week after being laid off finds me wondering why I've neglected this blog. I'm currently experiencing the self recriminatory state one goes into at the end of the dead end street having recently passed the Dead End sign. Brake, execute the multi-point 180 and head back to find the turn you missed. And then realizing that the turn you missed should have been as obvious as the nose on your face.

My conscience tells me not to be too hard on myself. In one week I've had an interview or two. Have another scheduled for tomorrow. And one or two inquiries from other potential employers. Met with more than one recruiter and talked with several more. Polished the resume a bit more and started working the neglected network of friends and former coworkers--neglect as a result of me working from my home office with little real world interaction. Note to self: get out more and talk with humans face to face.

I've even taken more than one meeting from possible business partners with ideas that may or may not pan out, but I'm not taking anything off the table until I replace my mainstream income.

So if anyone needs a C# dev guy with some architecture leanings, grab my resume and give me a shout.

TylerJensen2008web.doc (47.5 KB)

Url Utils Helper Class May Be Helpful

Sometimes the odd helper class is useful. This one might even be a decent candidate for some .NET 3.5 extension methods. These URL utilities are quite self explanatory and by no means are a complete set of URL helper methods that would be useful, but who knows, they might have something you're looking for.

using System;
using System.Collections.Generic;
using System.Text;

namespace HelperCode
{
    internal static class UrlUtils
    {
        internal static string GetTldFromUrl(string url)
        {
            string tld = UrlUtils.GetHostFromUrl(url);
            if (tld != null && tld.Contains('.'))
            {
                string[] parts = tld.Split('.');
                if (parts.Length > 0)
                {
                    tld = parts[parts.Length - 1];
                }
            }
            return tld;
        }

        internal static string GetHostFromUrl(string url)
        {
            string retval = null;
            try
            {
                Uri uri = new Uri(url);
                retval = uri.Host.ToLower();
            }
            catch
            {
                retval = null;
            }
            return retval;
        }

        internal static string GetSchemeFromUrl(string url)
        {
            string retval = null;
            try
            {
                Uri uri = new Uri(url);
                retval = uri.Scheme.ToLower();
            }
            catch
            {
                retval = null;
            }
            return retval;
        }
    }
}

If you have a better way to do it, please, by all means, let us know. There are no doubt better ways. :)