Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Friday, 4 September 2009

How To Create Web Server Controls with Smart Tags

General Assumptions
For the sake of this blog I will assume that you know and understand the differences between web user controls and web server controls. This blog concentrates on the latter and how you can create server controls that will present the developer with intuitive and helpful tools at design time for setting the basic options of the control.

Introduction
Throughout this blog I will be referring to a recent server control I developed that would render a carousel style news feed at run time. I wanted the server control to integrate will into the Visual Studio toolbox and to be easily configurable by the developer at run time using the familiar Smart Tag presentation you're probably familiar with. The code examples in this blog will be in C#.

Requirements of the Control

  1. The control needed to be data bindable.
  2. The control needed to be stylable (i.e. allow the developer to set whatever visual styles they wanted)
  3. The control needed to present as many properties within the Smart Tag as possible
Getting Started
The ASP.NET Server Control template creates the following basic code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyNamespace
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]
public class WebCustomControl1 : WebControl
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
String s = (String)ViewState["Text"];
return ((s == null) ? String.Empty : s);
}

set
{
ViewState["Text"] = value;
}
}

protected override void RenderContents(HtmlTextWriter output)
{
output.Write(Text);
}
}
}

This code is very helpful in itself. First of all, it defines a couple of useful attributes, most notably ToolboxData. This attribute defines the string that will be created in the markup when the developer using your control drags and drops an instance of it onto the designer work area.
Secondly it creates a demo property called "Text" that is defined as the default property by the DefaultProperty attribute. The "Text" demo property has several attributes set:

[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]

I won't go into the details of all of these attributes other than to say that the Category attribute specifies the category that this property will be displayed under on the properties grid for the control (within the Visual Studio design environment), and the DefaultValue attribute allows you to set the default value for this property.

Moving On
You may have noticed that the template generated code inherits the WebControl class. This is the base class for all web server control, but is not the only one available to you. Check out the MSDN documentation to view a complete list of base classes you can extend to suit your needs. Because my control was to be a data bound control I extended the DataBoundControl class, as follows:

public class DataBoundCarousel : DataBoundControl, INamingContainer

I won't go any further into the mechanics of my control as the purpose of this blog is to help you understand what's necessary in order to provide other developers with the cool Smart Tags that are available in VS.

Creating the Designer Class

The Designer for your control is defined with the Designer attribute, declared above the class declaration, as follows:

[ToolboxData("<{0}:DataBoundCarousel runat=server></{0}:DataBoundCarousel>")]
[Designer(typeof(DataBoundCarouselControlDesigner))]
public class DataBoundCarousel : DataBoundControl, INamingContainer
The DataBoundCarouselControlDesigner class is actually a very basic class which extends the appropriate base designer class. In my case this was the DataBoundControlDesigner class, but for your needs may be different. There are a couple of members of the base class that you need to implement in your class. The GetDesignTimeHtml method can be overriden if you want your class to return custom HTML at design time.

Getting an understanding of this Designer class took me a little while and a good few code examples before it sunk in. Let's look at the example from my code. First of all you must override the Initialize method, which takes an IComponent paramter. This parameter will be passed by the designer in VS and will be a handle to your server control. Store this in a private field within your Designer:


private DataBoundCarousel _myControl;
public override void Initialize(IComponent component)
{
base.Initialize(component);
_myControl = (DataBoundCarousel)component;
}


Moving on to the most important base class to override, the ActionLists property. This property returns a DesignerActionListCollection object.

public override DesignerActionListCollection ActionLists
{
get
{
_actionLists = new DesignerActionListCollection();
_actionLists.AddRange(base.ActionLists);
_actionLists.Add(new DataBoundActionList(this));

return _actionLists;
}
}
This read-only property instantiates a private field as a new DesignerActionListCollection object. It adds any ActionLists from the base class and then, most importantly, adds a new custom object, DataBoundActionList, which we'll look at in detail next. In my code the
DataBoundActionList class is a private class within the Designer class. This means that it has access to the _myControl private field member of the Designer class. Let's look at some important parts of this class. First of all, its definition and constructor:

private class DataBoundActionList : DesignerActionList
{
private DataBoundCarouselControlDesigner _parent;

public DataBoundActionList(DataBoundCarouselControlDesigner parent)
: base(parent.Component)
{
_parent = parent;
}
Notice that the constructor receives a handle to the containing Designer class, which it then stores in a private member field.

Before going any further into the description of the DataBoundActionList class, I'll now go straight into describing the styling properties of my contro, which will then lead me back nicely to the DataBoundActionList class.

I defined several areas of my control that would apply different CSS classes at run time. Rather than hard code these CSS classes into the rendered HTML I wanted to allow the developer using my control to set the contents of these CSS classes at design time. I therefore created properties of my control that would take the styling created by the developer. Here's an example of one such property:

[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Editor(typeof(MultiLineEditor), typeof(System.Drawing.Design.UITypeEditor))]
public string ImageStyle
{
get
{
string _imageStyle = "";

if (ViewState["ImageStyle"] != null)
{
_imageStyle = (string)ViewState["ImageStyle"];
}

return _imageStyle;
}

set
{
ViewState["ImageStyle"] = value;

if (IsDesignMode)
{
//Notification so that the VS PropertyGrid detects the change
IComponentChangeService _changeService = (IComponentChangeService)this.Site.GetService(typeof(IComponentChangeService));
_changeService.OnComponentChanged(this, TypeDescriptor.GetProperties(this).Find("ImageStyle", true), "foo", "foo2");
}
}
}

The discerning reader will notice a couple of things in the above code that I haven't as yet mentioned. For example, what does the Editor attribute do? Where is MultiLineEditor defined? What is the IsDesignMode property?

1) The
Editor attribute allows us to define a control that the property grid will display when the developer clicks on the property in the Property Grid. I chose to create a custom control, because I wanted the developer using my control to have a multiline textbox to edit their CSS in.

2) The complete code for my
MultiLineEditor class is below:

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class MultiLineEditor : UITypeEditor
{
public MultiLineEditor()
{
}

public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}

//displays the UI for value selection
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (value.GetType() != typeof(string) )
{
return value;
}

IWindowsFormsEditorService _editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (_editorService != null)
{
//Display a multiline text box
TextBox _textBox = new TextBox();
_textBox.Text = (string)value;
_textBox.Multiline = true;
_textBox.AcceptsReturn = true;
_textBox.Height = 125;

_editorService.DropDownControl(_textBox);
return _textBox.Text;
}
return value;
}

}
A few things worthy of note here... First, GetEditStyle method allows us to return the way that the designer will present the control. The enumeration is basically, None, Modal or DropDown. Second, the EditValue method is where we create the control that will be returned. I'm not going to lie and say that I fully understand the need for the IWindowsFormsEditorService object, but needless to say, it works. And, if it ain't broke...

3) IsDesignMode is a property that allows me to evaluate whether or not the code is being run from the VS design mode, or at run time. Although there is a DesignMode property a small caveat comes into play here in that the
DesignMode
property only returns true if the hosting control is in design mode. This custom property allows the code to get a more useable handle on the real design mode of the control.


private bool IsDesignMode
{
get
{
Control ctrl = this;
while (ctrl != null)
{
if (ctrl.Site == null)
return false;
if (ctrl.Site.DesignMode == true)
return true;
ctrl = ctrl.Parent;
}
return false;
}
}
So far, I've shown you the code that will allow the proper rendering of the property in the VS Property Grid, but we now need to return to the DataBoundActionList class to see what needs to be done to render a Smart Tag.

The base DesignerActionList class of my DataBoundActionList class contains a method that must be overriden, called GetSortedActionItems. This method is where we return each of the items that will appear on our Smart Tag.

public override DesignerActionItemCollection GetSortedActionItems()
{
DesignerActionItemCollection _items = new DesignerActionItemCollection();
_items.Add(new DesignerActionHeaderItem("Configure Data"));
_items.Add(new DesignerActionPropertyItem("SortOrder", "Sort Order", "Configure Data"));
_items.Add(new DesignerActionMethodItem(this, "ConfigureDataBindings", "Configure..."));

_items.Add(new DesignerActionHeaderItem("Styles"));
_items.Add(new DesignerActionPropertyItem("SummaryStyle", "Summary Style:", "Style", "Sets the style of the summary section of the carousel"));
_items.Add(new DesignerActionPropertyItem("TabStyle", "Tab Style:", "Style", "Sets the style of the tabs on the carousel"));
_items.Add(new DesignerActionPropertyItem("CurrentTabStyle", "Current Tab Style:", "Style", "Sets the style of the currently selected tabe on the carousel"));
_items.Add(new DesignerActionPropertyItem("ImageStyle", "Image Style:", "Style", "Sets the style of the images displayed on the carousel"));

_items.Add(new DesignerActionHeaderItem("Misc"));
_items.Add(new DesignerActionPropertyItem("CycleInterval", "Animation Cycle (ms):", "Misc", "Sets the style of the images displayed on the carousel"));
_items.Add(new DesignerActionPropertyItem("MaxNumberToDisplay", "Max. number of articles:", "Misc", "Sets the maximum numbeer of articles displayed on the carousel"));
_items.Add(new DesignerActionPropertyItem("EmbedJQuery", "Embed jQuery", "Misc", "Switch off jQuery embedding if the hosting page already contains a reference to the jQuery library"));
_items.Add(new DesignerActionPropertyItem("AutoAnimate", "AutoAnimate", "Misc", "Switch off auto animation when you do not want the carousel to automatically rotate through articles"));

return _items;
}
There are various Designer Action Items that can be added, but I'm going to focus here on the DesignerActionPropertyItem class. This class takes the name of the property as its first constructor argument, the display text as its second, the section of the Smart Tag it will reside in as its third, and a description of the property as its fourth. So, let's look at the line that defines the Smart Tag panel item for the ImageStyle property:

_items.Add(new DesignerActionPropertyItem("ImageStyle", "Image Style:", "Style", "Sets the style of the images displayed on the carousel"));
Now, let's look at the code of the property that this panel item will call:


[Editor(typeof(MultiLineEditor), typeof(System.Drawing.Design.UITypeEditor))]
public string ImageStyle
{
get
{
return _parent._myControl.ImageStyle;
}
set
{
_parent._myControl.ImageStyle = value;
}
}
Notice that this property sets and gets the corresponding property of the control. Remember that we are here looking at the code at the level of the DesignerActionList class. This class is purely for use at design time. What we're really interested in is setting the properties of our control for use at run time.

Notifying the Design Environment
One of the quirks I came across during th development of my control was that the markup generated for my control wouldn't update when I changed the values of properties from within my Smart Tag panel. I was preplexed for a little while about this and eventually found out how to raise an event that would notify the design environment when my property had changed. Basically, in the setter for each of the properties on my control I call the following code:
               if (IsDesignMode)
{
//Notification so that the VS PropertyGrid detects the change
IComponentChangeService _changeService = (IComponentChangeService)this.Site.GetService(typeof(IComponentChangeService));
_changeService.OnComponentChanged(this, TypeDescriptor.GetProperties(this).Find("ImageStyle", true), "foo", "foo2");
}
Knowing this in advance could save you a load of hassle at development time.

Conclusion
If you're developing custom server controls at this kind of level you aren't a beginner programmer. So, I'll hope you will excuse the fact that a lot of code has been omitted from this blog. I've provided code examples for all of the important details and I hope that there's enough information here to get you rolling with the development of your own controls.
Don't forget that all of the classes and ample documentation is provided on MSDN.


Tuesday, 21 July 2009

Delegates Explained in Plain English

Delegates are fundamental to the .NET Framework (events and callbacks wouldn't work without them) and can be extremely powerful to the .NET Developer once they come to grasps with exactly what they are and how to use them. In this blog I will consider aspects of a real world situation in which delegates are useful, after which I will explain, in illustrative terms exactly what delegates are all about. You will see how delegates are an intrinsic part of the events structure in the .NET framework, but also why they are useful in their own right. First, though, we need to understand a little about the origins of delgates in the .NET framework.

The origins of delegates

Delegates in .NET languages such as C# and VB.NET are akin to function pointers in C++. I have found that simply being aware of this pseudonym is extremely helpful in understanding delegates. The term helps us to understand that delegates allow a developer to provide a pointer to a method/function/sub etc. But when would a developer find this to be useful?

Where delegates are needed

Let's say, for example, that you are developing a Windows Forms application and you want to open a new instance of a form. You want your new form to do some work and update its opener at some point down the line.

To expand, let's take a real world example. I developed a Windows Forms application in C# that was used for managing staff and contracts within a cleaning business. This was an MDI application and had toolbars on the MDI parent form with lists of staff and contracts so that the user could easily select a member of staff or a contract to work on. When the user selected a member of staff or contract a new form was opened. There was also, as you would expect, forms for creating new staff members and new contracts. These forms needed to update the main form whenever a new member of staff or a new contract was added to the system so that the main form could refresh its lists. In a basic application you might accomplish this by opening these forms modally directly from the main form and then updating the lists when the new staff form closes. Something along the lines of:

//... MainForm code ...
NewStaffForm _nuForm = new NewStaffForm();
_nuForm.ShowDialog();

//Assume that the user clicked the OK button on the
//NewStaffForm and added a new member of staff
RefreshStaffList();

However, this is extremely limiting. The ShowDialog() method for opening the NewStaffForm form holds execution of the subsequent code within the MainForm until the NewStaffForm has closed.

What if you want your application to be more flexible than that and keep your MainForm useable while the NewStaffForm is in use? What if you want your NewStaffForm to do more than just notify your MainForm that it's created a new user? Say, for example, you want it to pass information back to the MainForm? This is where delegates come in.

In particular, in this instance, an event would be useful; but as you will see, in .NET delegates are inseparable from events.

Revising our code to use delegates and events

No doubt you're very familiar with events and have made extensive use of events belonging to other objects. However, until you actually create your own events you probably don't really know or care what's going on. So, let's revise our code and explain what we're doing at each stage.

First, we want to declare an event handler in our code. It doesn't really matter where this event handler is declared so long as it has public scope so that it can be seen by other objects. A delegate can be declared outside of a class declaration, as it is essentially a type declaration, just as a class is.

public delegate void NewStaffCreatedHandler(StaffMember NewStaffMember)

Notice that this event handler is actually a delegate. Also, notice that it takes a parameter of type StaffMember. This is a custom type specific to this program. It's details are not relevant to this blog, so I'll go no further in describing it.

Next, we declare an event in our NewStaffForm.

public event NewStaffCreatedHandler NewStaffCreated;


Notice that the event has, as its type, the event handler we just declared.

Next, we write code to raise the event. This looks very much like a method call:

protected void CreateNewStaffMember()
{
StaffMember _newStaffMember = new StaffMember();
//... Code to create the new StaffMember...
//Raise the event
NewStaffCreated(_newStaffMember);
}
Where exactly is the code that runs when the event is raised? Remember what we said earlier about the origins of delegates lying in C++ function pointers. As I said, remembering this pseudonym helps to understand what delegates are all about.

When the event is raised we are actually calling the function(s) (or method(s)) that the delegate points to. How do we point the delegate to a method? Well, where events are concerned I'm willing to bet that it's something you already know how to do. We simply assign a method to the event be doing the following in our MainForm form.

//Create an instance of the NewStaffForm and assign a method to the NewStaffCreatedHandler
NewStaffForm _nuForm = new NewStaffForm();
_nuForm.NewStaffCreated += new NewStaffCreatedHandler(NewStaffForm_NewStaffCreated);
_nuForm.Show();

//This is the method that the delegate points to
void NewStaffForm_NewStaffCreated(StaffMember NewStaffMember)
{
RefreshStaffList();
NewStaffMember.AddedToList = true; //Do something with the StaffMember object that was passed with the delegate
}

Explaining what's happening in Plain English

Why are delegates called delegates?

In the real world a delegate is usually a person. What function do they serve? Well, imagine a large company wants to have a presence at a conference. The whole company can't relocate to the conference venue for its duration - that would be impractical. Rather, the company assigns a delegate (or delegates) to go and represent the company at the conference. The delegate might be given specific instructions about how he or she is to behave when there, which hotel they are to stay in, what their budget for food & drink is etc, but the delegate, being a human being, has relative freedom besides these constraints. When the delegate returns from the conference he or she may have to report back to the company about it.

In the .NET framework a delegate fulfils a similar purpose. Where one class may wants to be represented within another class it can use a delegate. This is a lot more efficient that passing itself to the other class in its entirety, and is a lot more flexible. The delegate has to conform to certain limitations, though, just as the real world delegate does.

When a delegate is declared it is declared much along the lines of a method/sub/function declaration. For example, in C#, a delegate declaration might look like:

public delegate void NewStaffCreatedHandler(StaffMember NewStaffMember)

It is given a scope public, a return type void (although it could equally be any other type), and specifies parameters. This constitutes the agreement as to how the implementation of the delegate (i.e. the method/sub/function it points to) must behave. In other words, any method/sub/function that this delegate points to must return a void and take a StaffMember object parameter.

The most common event handler delegate EventHandler, for example, has the following declaration:

public delegate void EventHandler(object sender, EventArgs e);

All events are of a delegate type. In other words, all events are declared with a specific delegate as their representative. For example, a delegate at a Microsoft conference could report back on an event that a delegate at an Sun conference couldn't (although they in turn could report back on an event that the Microsoft delegate couldn't), because they weren't in attendance at the same conference.

So, if you wanted to declare an event in your program that used the standard EventHandler delegate you would declare it as follows:

public event EventHandler MyEvent;

Delegates aren't restricted to events

Although we've used events as a springboard for our explanation of delegates, there's no reason to limit delegates to this useage. In the MDI application I mentioned above I didn't actually use events at all (although, as can be seen, I could easily have). I knew that I wanted my child forms to update my parent forms by means of a function call. This created the environment for the use of a delegate, but to save on the the extra declaration of an event in my child form I simply declared a constructor for my child forms that took my delegate as a parameter. For example:

public delegate void NewStaffCreatedDelegate(StaffMember
NewStaffMember
);
public class NewStaffForm : Form{
public NewStaffForm (NewStaffCreatedDelegate callbackDelegate){
//Constructor logic
}
}

Then, when I wanted to callback to my parent form I simply invoked the delegate:

callbackDelegate(newStaffMember);

Passing a delegate to the constructor of the child form is very easy. Simply pass the name of the method that you want the delegate to point to. For example:

NewStaffForm myChildForm = new NewStaffForm(myCallBackMethod);
Don't forget, though, that the method being passed MUST agree to the rules set out for the delegate. So, it's signature must be the same as that of the delegate.

void myCallBackMethod(StaffMember newStaffMember){
//Implementation logic
}

Summary

In essence, delegates allow one class to invoke code in another class, without necessarily needing to care where that code is, or even if it exists at all...

Let's go back to the conference scenario to explain. Microsoft may host a conference and send out invitations to many different partner companies. At the conference one of their lead developers may provide a sneak preview of a new product. Delegates in attendance may be given a beta copy to take back with them for trial. Microsoft doesn't care whether or not all of the companies they invited chose to send a delegate or not. Their conference won't halt just because one company declined to be represented.

Likewise, one class may expose a property, method parameter or event that allows another class to send a delegate to its code. The delegate (or more to the point the implementation of the delegate, the method/sub/function that the delegate points to) will have to conform to the delegate's signature. Most classes that send a delegate may choose to provide an implementation (i.e. logic for the method/sub/function) but some may not. The inviting class doesn't really care... it will still do what it does and make use of the delegate. For example, all TextBox control's expose a KeyPress event, but not every form that uses a TextBox control will choose to provide an implementation for the KeyPress handler. The TextBox control will still work, it's just that nothing will happen when a user presses a key within it - because no implementation of the delegate has been provided by the form.

In conclusion, as you will see from the above, once you understand what delegates are for, and what they enable, you will likely start to realise many different scenarios in which you can use them. I strongly believe that you can't really claim to be a .NET developer without understanding this fundamental part of the framework. If you've struggled to understand delegates in the past, or even if you've never really cared much about them before, I hope this blog will help to clarify matters and help you to become a better programmer.

Sunday, 19 July 2009

Aspects of Polymorphism in .NET Part 4 - Interfaces

If you've read parts 1-3 of this blog you'll be aware that we've used the real world objects, cars, to draw a parallel with, and explain, classes, inheritance and abstraction. I hope that, by this stage, you are beginning to undertand and recognise the advantages that come from properly object orienting your code. Flexibility for future development is a key aspect of proper OO design.

Although the code examples in this BLOG have been written in C#, one of the .NET languages, the principles apply to all Object Oriented languages.

So, we now come to Interfaces. What role do they have in object oriented programming?

Contracts

I have often read that Interfaces can be likened to contracts. The thinking behind this analogy is that a class implementing an interface MUST implement ALL of the methods and properties declared by the interface, much the way that an employee MUST carry out all of the responsibilities contained in his contract of employment if he wants to keep his job.

However, I don't really find this analogy to be particularly helpful as it doesn't really explain why you'd bother to create or implement an interface in the first place. So, I'm going to explain the use of interfaces by extending our hypothetical car model already used throughout this BLOG. I sincerely hope that this will clarify the use of interfaces for any of you who are a little confused about them.

Recap

At the end of part three you should have started to see that by abstracting a "Car" class and implementing that abstract class in our "Focus" class we could then build other classes that made use of Cars (generic and flexible) rather than specific models such as Focus (narrow and restrictive). An abstract class was ideal for the "Car" because it allowed us to implement logic that was common to all cars within the abstract class, and declare abstract methods for logic that would have to be implemented by sub classes.

Manual or Automatic?

In the UK (where I'm from) 90% of the cars on the road are manual transmission with the vast minority being automatic. Drivers who take their driving test in an automatic car are restricted to only being able to drive automatic cars. On the other hand, those who pass their test in a manual car can drive either manual or automatic. Modelling this behaviour in our example case is an ideal environment for interfaces.

Although it's not compulsory, it is common practice to precede the name an interfaces with a capital "I". So, let's create interfaces that define manual and automatic cars.

    public interface IManual
{
bool ClutchDepressed
{
get;
set;
}
void ShiftUp(int gearFrom, int gearTo);
void ShiftDown(int gearFrom, int gearTo);
}
public interface IAutomatic
{
void ShiftDrive();
void ShiftReverse();
void ShiftPark();
}
You will notice that our interfaces contain no implementation (i.e. logic that says how to do any of the things declared), they simply declare methods and properties that any implementing classes MUST provide logic for.

So, when the hypothetical engineers at Ford build different models of the Focus, they will implement one of these interfaces depending on the kind of transmission they will be using. Let's go back and update our code in order to implement one of these interfaces.

    public class FocusAuto : Focus, IAutomatic
{
public FocusAuto(Guid keyCode)
: base(keyCode) { }
public FocusAuto(Guid keyCode, int numDoors) : base(keyCode, numDoors) { }

public void ShiftDrive()
{
//... Logic to change the gear into Drive and
// then automatically through the gears as the car moves ...
}
public void ShiftReverse()
{
//... Logic to change the gear into Reverse ...
}
public void ShiftPark()
{
//... Logic to change the gear into Park ...
}

}
You'll notice that I've created a new class, called FocusAuto. This means that we've managed to avoid changing our existing Focus class. Focus, still implements Car, so we still benefit from all of the logic contained in Focus and Car. However, as highlighted in blue, the new FocusAuto class implements the IAutomatic interface. As a result it MUST implement the three methods declared by the interface.

The Benefits

Why put this definition in an interface? After all, the FocusAuto class could easily have contained the logic without implementing the IAutomatic interface. Simply remove the , IAutomatic from the class definition and the code will still compile...

The reason is simple and yet very powerful - and remarkably similar to the benefits we derived from abstracting logic into a Car class...

Earlier I mentioned that interfaces are often likened to contracts. Think about what contracts do... For example, your employment contract defines what is expected of you as an employee. However, it also serves as a marker or identifier for YOU. If you have a contract that defines the role of a C# developer that is what you are.

Interfaces do the same for classes - they act as identifiers for what the class is, or does. So, we can now diffentiate drivers based on what they are allowed to drive. Let's create a new class to demonstrate this

    public class AutomaticDriver
{
private Car myCar;
public IAutomatic MyCar
{
get
{
return (IAutomatic)myCar;
}
set
{
myCar = (Car)value;
}
}
public void Init()
{
Guid _keyCode = new Guid();
if (myCar != null)
{
myCar.Start(_keyCode);
myCar.Accelerate(0, 50);
myCar.Brake();
}
}
}

Because our AutomaticDriver class doesn't really care about who made the Automatic car it drives all it has to do is check that the car is an automatic. Therefore any car that implements the IAutomatic interface will be allowable.
            FocusAuto myAuto = new FocusAuto(new Guid());
AutomaticDriver driver = new AutomaticDriver();
driver.MyCar = myAuto;

Summary

Throughout this BLOG on polymorphism you have seen that there is much to be gained by OO design - designing at the interface level rather than the object level. In fact, this is the basic premise of Design Patterns (recommended for further reading).

I have used a real world parallel in order to convey these concepts because I often find it easier to understand new concepts by looking for every day instances around me. I hope you have found this series to be helpful and insightful.

Friday, 17 July 2009

Aspects of Polymorphism in .NET Part 3 - Abstract Classes

Part Three: Abstraction

All of us are aware of abstract concepts, although perhaps we aren't aware that we're aware. To explain... all of us know that there are things we can touch, possess, and things that we can't. For example, we all eat food, but we never actually have a food. Food is an abstract concept and we actually eat instances of food - apples, hamburgers, pizzas, carrots, etc.

Abstraction is at the top level of most things we're familiar with on a day to day basis. In our Ford Focus illustration we were dealing with a concrete instance of an abstract concept - vehicle. Although a person may be said to own a vehicle, it's meaningless without specifying the type of vehicle he or she possesses. For most of us this is a car, but for some it might be a plane, a boat, a bike, a helicopter etc. We then further solidify things by becoming more and more specific about things - what make, model, variation of car we have, for example.

In programming terms abstraction allows us to define a very loose model for something without specifying exactly how the implementation will be handled. Abstraction comes in varying degrees in the programming world. There are Interfaces, which are completely abstract (contain absolutlely no implementation code), and abstract classes, which can contain a mixture of abstract methods and implementation code. This will all be explained before long, so don't worry if you don't understand these terms just yet.

We'll start by moving one step up the vehicle abstraction hierarchy from our Focus, to the Car to explain abstract classes. Cars come in all different shapes and sizes, but all working cars share certain characteristics, no matter how new, old, cheap or expensive they are. They all start, stop, move, turn etc. How these characteristics are accomplished though, can be different from one car to the next. For example, one manufacturer may start the car by a simple key turn, another by a push button, yet another by fingerprint recognition. On the other hand, though, some things are common between all cars - they are all driven by an engine, stopped by brakes etc. These rules apply for cars, but not for other types of vehice - sailing boats, for example, are driven by the wind and stopped (if in a hurry) by an anchor.

So, if we were to extend our model code for the Focus we would have to say that our Focus is a concrete implementation of a Car (abstract class). Of course, because we're building our code in the order in which wer're covering the topics in this blog, we'll next be building our abstract "Car" class. In pratice, we would design our classes using a modelling tool such as UML, designing interfaces and abstractions up front - the inverse to the way wer'e doing things in this blog - and code concrete classes on the basis of our abstractions. For further reading on the matter Google "Design Patterns" or "Gang of Four".

There is a lot to be said for abstracting functionailty, but I strongly believe that you need understand the bigger picture first.

Let's have a look at how we code an abstract class in C#:

namespace Ford
{
public abstract class Car
{
public abstract void Start(Guid keyCode);
}
}


This is a very basic start, but it demonstrates all that we need to show for now... First of all notice the use of the keyword abstract. This marks the class as being abstract, so instances of this class cannot be created. So,

Car c = new Car();
will result in a compilation error:
Cannot create an instance of the abstract class or interface 'Ford.Car'
Next we have an abstract method:

public abstract void Start(Guid keyCode);


Notice that this method doesn't have a body (i.e. no curly braces).
That's because the method is abstract - its implementation, or how it will start, must
be coded in a class that implements this abstract class. We'll soon see
how this affects the Focus class, which we'll alter to implement the Car class.


However, abstract classes can contain implementation logic too, which is then inherited by the classes that implement it. For example, since in our fairly basic example, we can safely assume that all cars will accelerate by engaging the engine and stop by engaging the brakes, we can promote this logic to the abstract class level. Then all cars will benefit from this standard logic.
Our modified abstract class now looks like this:
   public abstract class Car
{
protected Engine _engine = new Engine();
private double _currentSpeed;
private Brake[] _brakes = new Brake[4] { new Brake(), new Brake(), new Brake(), new Brake() };

public abstract void Start(Guid keyCode);

public void Accelerate(double initialSpeed, double endSpeed)
{
while (_currentSpeed <>
{
_engine.Throttle();
}
_engine.Idle();
}

public void Brake()
{
_brakes[0].Apply();
_brakes[1].Apply();
_brakes[2].Apply();
_brakes[3].Apply();
}

}

Now we'll look at the changes we need to make to our Focus class in order to implement the Car class.

As a reminder, let's look at the code as it was:


public class Focus{
private Engine _engine = new Engine();
private double _currentSpeed;
private int _doorCount = 4;
private Guid _keyCode;

public Focus(Guid keyCode){
//Default constructor
_keyCode = keyCode;
}

public Focus(Guid keyCode, int numDoors) : this(keyCode)
{
_doorCount = numDoors;
}

public void Start(Guid keyCode)
{
if(keyCode == _keyCode)
_engine.Start();
}

public void Accelerate(double initialSpeed, double endSpeed)
{
while(_currentSpeed < endSpeed){
_engine.Throttle();

}
_engine.Idle();
}

public int DoorCount{
get{
return _doorCount;
}
set{
_doorCount = value;
}
}

// ...
// ...

}


In order to implement the new Car abstract class the following changes need to be made:

   
public class Focus : Car
{
private int _doorCount = 4;
private Guid _keyCode;
public Focus(Guid keyCode)
{
//Default constructor
_keyCode = keyCode;
}
public Focus(Guid keyCode, int numDoors)
: this(keyCode)
{
_doorCount = numDoors;
}
public override void Start(Guid keyCode)
{
if (keyCode == _keyCode)
_engine.Start();
}
public int DoorCount
{
get
{
return _doorCount;
}
set
{
_doorCount = value;
}
}
// ...
// ...
}


Notice the changes to the class:
1) We've added : Car to the class declaration. Just as with the extension of Focus into FocusLE, this notifies the compiler that we are going to be implementing the Car abstract class.
2) The Accelerate method has been removed since this logic is now contained in the abstract class.
3) We still have the Start method, although we've had to add the [italic]override[/italic] keyword to the method statement.

Why do we get rid of Accelerate, but keep Start? Because Start is declared as an abstract method in the Car class. In other words it must be implemented in a child class, such as "Focus". On the other hand, Accelerate contains implementation logic within the abstract "Car" class and therefore doesn't need to be overriden in the "Focus" class - although it [italic]could be[/italic] if needed.

Now, when we create an instance of Focus we get access to the Accelerate and Brake methods. Let's create a new class, called "Driver" and demonstrate this inheritance:

    public class Driver
{
public void Init()
{
Guid _keyCode = new Guid();
Focus myFocus = new Focus(_keyCode);
myFocus.Start(_keyCode);
myFocus.Accelerate(0, 50);
myFocus.Brake();

}
}
The code highlighted blue demonstrates the fact that the "myFocus" object (i.e. the instance of the "Focus" class) can Accelerate and Brake even though "Focus" doesn't define these methods.

Why?

You may be wondering - "why is any of this useful?" Well, now that we've abstracted things out to the level of "Car" we can deal at that abstract level. Say for example, we were creating a class called "Garage". We can now easily build that "Garage" class around Cars rather than Focuses.

    public class Garage
{
public void Service(Car aCar)
{
//...
//Code to Service the care
//...
}
}
Because every "Focus" is also a "Car" (by virtue of the fact that it has implemented the "Car" abstract class) this, and any other class that implements the "Car" abstract class can now be serviced at the "Garage".

Once you understand the principles of abstraction it doesn't take long to realise the massive potential for it to make your code more flexible and extensible.

Summary

This tutorial has demonstrated what abstract classes are, and by the time you've finished reading this series of blogs on polymorphism I hope you will feel sufficiently equipped to go on to further reading, such as books on Design Patterns. These books will help you to get a stronger grasp on the far reaching benefits of abstraction.

The next and final part of this blog series will deal with interfaces.

Aspcts of Polymorphism in .NET Parts 1 & 2 - Inheritance

Introduction

.NET Developers come in various shapes and sizes, not only physically, but also in terms of their expertise and experience. The polymorphic nature of the .NET Framework now allows their code to benefit from similar diversity. Sadly, though, it is entirely possible with .NET languages and tools, such as Visual Studio 2008, for developers to build programs and web sites without necessarily needing to know or understand the underlying complexity of what they are doing. I've come across so-called developers whose approach to solving problems has greatly improved their search engine skills as they scour the internet for code samples they can lift to fix the problem they're currently facing. Sadly, though, their attitude towards actually understanding and getting to grips with the problem domain is one of laziness. For this reason developers can work commercially, producing viable code and making extensive use of the vast array of controls and tools at their disposal, yet not fully understand such basic lower level concepts as abstraction, inheritance and polymorphism. To be fair, though, this is quite understandable. After all, much of the documentation available on these topics is far from light reading, and tends to go to much greater depth than is necessary for the average beginner wanting to gain a basic understanding. This blog will therefore provide an easier access into these areas of object oriented (OO) programming techniques.

Part One: Object Orientation - What's all the Fuss?

I first came into .NET languages after years of developing solely in Visual Basic. Newer developers, who have only really got into the programming game since the inception of the .NET Frameworks will no doubt be a little confused by this statement. To explain... Visual Basic existed as a much more simple language prior to VB.NET. A VB developer was largely looked down upon by other members of the programming community (Java, Delphi, C++ etc) because Visual Basic was, rightly, viewed as an inferior language. Why? Because it masked a lot of complexity from the developers using it. Inheritance wasn't even an option. During this period I started learning a little Java and had my first exposure to proper OO programming. At about the same time the first version of the .NET Framework was seeing the light of day, and my movement into C# from Java was therefore very organic. So, what's all the fuss about? Well, Object Oriented programming allows a much more flexible and extensible approach to developing your code than you would otherwise have. Let's explain by means of a real world parallel, as I often find these to be the best aids.

If you drive, you no doubt, unless you're very wealthy (in which case, why are you reading this blog?), own a car built on a production line by one of the world's major car manufacturers. Your car started its life on a production line along with a load of other cars just like yours. Let's say, for example, that you drive a Ford Focus. Although your Focus is identical in shape and size to all other Focuses manufactured at the same time as yours, it isn't necessarily identical in all areas. Ford offers a diverse range of trim levels across the Focus range that affects such items as wheels, tyres, engine size, fuel type, leather or cloth seats etc. However, although you may have requested a certain level of individuality for your car, Ford didn't have to send their designers back to the drawing board in order to build your car. They stuck with the basic design of the Focus and simply changed peripherals. This is a real world instance of what Object Oriented programming techniques allow. A programmer can develop a class that does everything he or she wants it to. However, unless he seals the class, which prevents it from being extended (although Method Extensions in .NET Framework 3.5 can provide a workaround for developers wishing to extend sealed classes) another developer can extend or override aspects of the class so that it fits their own individual needs. This is called polymorphism (poly meaning "many" and "morph" meaning shape). When you stop to think about it you'll soon realise the potential benefits you can reap from this.

Part Two: Inheritance

If we were to draw a parallel to the above example in the programming world, engineers at Ford would have built what's called a base class and named it something like "Focus". This class would define and implement various properties and methods. For example:

public class Focus{
private Engine _engine = new Engine();
private double _currentSpeed;
private int _doorCount = 4;
private Guid _keyCode;
public Focus(Guid keyCode){
//Default constructor
_keyCode = keyCode;
}
public Focus(Guid keyCode, int numDoors) : this(keyCode)
{
_doorCount = numDoors;
}
public void Start(Guid keyCode)
{
if(keyCode == _keyCode)
_engine.Start();
}
public void Accelerate(double initialSpeed, double endSpeed)
{
while(_currentSpeed < endSpeed){
_engine.Throttle();

}
_engine.Idle();
}
public int DoorCount{
get{
return _doorCount;
}
set{
_doorCount = value;
}
}
// ...
// ...
}
Now, let's say they decide to release a limited edition Focus that has a push button start, instead of a traditional key turn. One safety condition is that the clutch has to be depressed before the engine can be started. Several other novel features are added, but for the sake of simplicity this is the one we'll focus on (no pun intended). Since the code for the base class is pretty much as it needs to be, the engineers can use inheritance to extend the existing functionality. They therefore create a new object called "FocusLE" (LE = Limited Edition).

public class FocusLE : Focus{

}
By using the ":" operator the compiler is told that this new class inherits from the "Focus" base class. The new class inherits all of base class' public and protected methods and properties. However, we now want to create a new Start() method that takes an additional parameter:

public class FocusLE : Focus{
public void Start(Guid keyCode, bool clutchDepressed){
if(clutchDepressed)
base.Start(keyCode);
}
}
Because the new class inherits from the "Focus" base class the new Start() method can invoke the Start() method in the base class by use of the base keyword once it has done its check to make sure that the clutch is depressed. However, we don't want to leave the old Start() method publically exposed. So we have to do what's called hiding the base class' method.

public class FocusLE : Focus{
public void Start(Guid keyCode, bool clutchDepressed){
if(clutchDepressed)
base.Start(keyCode);
}
//override the StartMethod in the base class
public new void Start(Guid keyCode){
//Do nothing
}
}
Because the engineers who created the the base "Focus" class didn't anticipate a later revision with a different start mechanism they didn't declare the base class' Start() method using the virtual keyword. That's why we use the new keyword when declaring the hiding method. We could leave it out but the compiler would issue a warning. This hiding Start() method means that trying to start the new "FocusLE" without providing the second parameter will do nothing. If we hadn't hidden this method of the base class in our new class the old Start() method would still have been available and we would have had a potential safety risk.

Had the original engineers looked ahead and declared the original Start method with the virtual keyword we would have been able to override this in the "FocusLE" class.

public class FocusLE : Focus{
public void Start(Guid keyCode, bool clutchDepressed){
if(clutchDepressed)
base.Start(keyCode);
}
//override the StartMethod in the base class
public override void Start(Guid keyCode){
//Do nothing
}
}
Part Three: Abstraction

In part three of this blog I will expand our example to explain the idea of abstraction in object oriented programming. Part Four will look at Interfaces and what they're useful for.