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

Thursday 23 September 2010

Tip of the day – A good use of auto implemented properties.

A very practical use of auto implemented properties could be to create a immutable lightweight class. An auto implemented property is a ‘property’ in C# without fields. The C# JIT Compiler generates the IL with a field for the auto implemented properties. (hence the name). The IL also replaces the Get and Set accessor stubs in the Properties to return and set the automatically generated field.

Take a look at the below code ( class ‘Books’). There are Title, Author and PublshedYear auto implemented properties. Notice the set is private, This makes the ‘Books’ class immutable.

autoprop

The tip is to use this kind of construct to replace structs when ever a reference type is required. Also notice that the constructor is made ‘private’. Simply because i find the factory method ‘CreateBook’  semantically appealing to call the private constructor rather than having to use the auto implemented property directly in the constructor for initializing the Books object.

Take a look at the IL for Books.,  Notice the ‘k__BackingField’ feild generated by the C# Compiler.

image

//////////////get_Author: string() IL////////////////////

.method public hidebysig specialname instance string
        get_Author() cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
  // Code size       11 (0xb)
  .maxstack  1
  .locals init (string V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      string ConsoleApplication1.Books::'<Author>k__BackingField'
  IL_0006:  stloc.0
  IL_0007:  br.s       IL_0009
  IL_0009:  ldloc.0
  IL_000a:  ret
} // end of method Books::get_Author

 

//////////////////set_Author:void(string) IL////////////////

.method private hidebysig specialname instance void
        set_Author(string 'value') cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
  // Code size       8 (0x8)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stfld      string ConsoleApplication1.Books::'<Author>k__BackingField'
  IL_0007:  ret
} // end of method Books::set_Author

Now, a demo of using the above immutable lightweight class

democode

Happy patterns discovery..

I’ve used the MSDN example here to illustrate.

Saturday 17 January 2009

Investigating Silverlight Exception: System.ArgumentException: Value does not fall within the expected range

Hi,

Good to be back in action after a long break. I just found this nasty little exception when i was adding a user control to a Grid in Silverlight 2. Took me some time to understand what was happening though, until i found that it was a known issue on the silverlight forum.

I managed to get a work around that problem which i promptly shared on the same forum.

System.ArgumentException: Value does not fall within the expected range at Ms.InternalXcpImports.MethodEx(IntPtr ptr, String name, CValue[] cvData)

Turns out that every container needs a unique 'Name' property to be set for it's child. I have managed to get it fixed with the following self explanatory code snippet.

private static int componentID = 0;

private Grid tableGrid;

FrameworkElement element; //this is a user control.

element.SetValue(Canvas.NameProperty, GetComponentID().ToString());

private static int GetComponentID()

{

return componentID++;
}

//This will not give the 'Value does not fall within the expected range' exception.

tableGrid.Children.Add(element);

Thursday 20 November 2008

Unit Testing Silverlight Apps

Inarguably SL2 applications are  a whole new experience of developing cross platform applications from managed code environments.

Unit Testing becomes very vital while developing for cross browser enterprise class applications. Visual Studio's tight integration of the Unit Testing framework is such an invaluable tool in the code production pipeline. Now, with the release of a unit testing framework for SL2 applications, the same experience can be leveraged.  SL2 applications can be developed in a test driven fashion now. It perfectly suits an agile team. A team which is constantly driven by change and is delivering on a constant basis, almost every day in some cases. Much like a team which does not have a release model. (Check out Jeff Wilcox's blog). I guess the Silverlight test framework was itself developed using an agile methodology.

The SL Unit testing framework has  proved to be an invaluable tool personally for me. It allows me to test SL applications on 3 different browsers (cheap guess if you are thinking which browsers ) even though i target IE mainly. :P.  I'll write about it with a test application soon in my next blog. Till then, check out these links..

Some Links:

Silverlight Toolkit - You can find components like dockpanel, treeview etc for SL 2, themes and of course the source code for controls with unit tests and the unit test framework itself.

Jeff Wilcox - The guy who develops actively on the SL unit test framework at MS.

Scott Gu's small demo program on SL unit testing - (If you don't know this man, you are not worth living, jump off a building NOW!)

MS Silverlight Unit Test Framework - MS unit test framework for SL 2.

Wednesday 19 November 2008

A Simple Multi-threaded Logger

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.IO;

namespace SudhirMurthy.Logger {

public interface ILog {

void LogToDisk(string msg);

}

interface ILoggerService {
ILog ILog {
get;
}
}

public class LogFile : ILog {

static List<string> messages;

//WriteToDisk delegate
private delegate void WriteToDisk(object sender, string fileName);

//WriteToDisk event
private static event WriteToDisk writeToDisk;

public static void WriteLog(string fileName) {
//Raise the event
writeToDisk(new object(), (fileName));
}

public void SendToDisk(object sender, string fileName) {

StreamWriter sw = File.CreateText(fileName);
foreach (string s in messages) {
sw.WriteLine(s);
}
sw.Close();
}

public LogFile() {
messages = new List<string>();
WriteToDisk mydelegate = new WriteToDisk(SendToDisk);
writeToDisk = new WriteToDisk(SendToDisk);
}

public List<string> Messages {
get {
return messages;
}
}

#region ILog Members

public void LogToDisk(string msg) {
Monitor.Enter(this);
messages.Add(msg);
Monitor.Exit(this);
}

#endregion
}

public class LoggerService : ILoggerService {

//TODO: Need to make it threadsafe..
private static ILog logInstance = null;

public LoggerService() {
logInstance = new LogFile();
}

#region ILoggerService Members

public ILog ILog {
get {
return logInstance;
}
}

#endregion
}

public class LoggerClient1 {

LoggerService logService;

public LoggerClient1() {
logService = new LoggerService();
}

public void Log() {
logService.ILog.LogToDisk(string.Format(
"I am Logging: {0}", this.ToString()));
}
}

public class LoggerClient2 {
LoggerService logService;
public LoggerClient2() {
logService = new LoggerService();

}
public void Log() {
logService.ILog.LogToDisk(string.Format(
"I am Logging: {0}", this.ToString()));
}
}

public class TestApp {

LoggerClient1 a;
LoggerClient2 b;

public TestApp() {

a = new LoggerClient1();
b = new LoggerClient2();
}

public void logClient1() {
for (int i = 0; i < 1000000; i++) {
a.Log();
}
}

public void logClient2() {
for (int i = 0; i < 1000000; i++) {
b.Log();
}
}
}

class Program {

static void Main(string[] args) {

TestApp app = new TestApp();
Thread t1 = new Thread(new ThreadStart(app.logClient1));
Thread t2 = new Thread(new ThreadStart(app.logClient2));


try {
t1.Start();
t2.Start();
} catch (Exception) {
throw;
}
t1.Join();
t2.Join();

//The main thread should technically wait until
//t1 and t2 should have finished and then execute
//the following
LogFile.WriteLog("log.txt");
}

}

}



I have demonstrated a simple multi-threaded logging mechanism here. The threads t1 and t2 share the static instance variable 'List<string> messages' while logging. The LoggerClient classes LoggerClient1 and LoggerClient2 each use the LoggerService to log messages. The log is finally written to disk by the the main thread. The LogFile class uses the Monitor.Enter(this) and Monitor.Exit(this) methods to allow locking while shared access to writing the log. This synchronizes the threads t1 and t2 to perform shared access writes without corrupting or overlapping the write operations. Another important thing to notice here is the methods t1.Join() and t2.Join() which is used to make the main thread wait until the threads t1 and t2 have finished executing.


If you try removing the Monitor.Enter(this) and Monitor.Exit(this) lines from the above code, you end up getting weird line numbers in your log.txt file. (enable line no's in visual studio and see log.txt). i.e the count of the log will never be as expected (2 million in the above case). By putting the above lines back, you get the expected value which is 2million lines of log. :). It takes about 5-6 seconds on my dual core for threads t1 and t2 to finish logging and the main thread to write to disk. :).  A bloated 93.4 MB file!!



My thread on MSDN Forums.



C0de

Wednesday 22 October 2008

A Simple RSS Reader in WPF

I present here, a simple Rss reader written almost entirely in XAML. I personally find WPF Data binding powerful and exciting to work with.

To start with, i've used the XmlDataProvider class to hook up the source to an rss feed and set it's XPath property to "rss/channel/item", so that i get all items in the channel.

The layout is an utterly simple dockpanel which has a stackpanel docked to the top, a status bar docked to the bottom and a grid which fills up the remaining space.

The databinding is self explanatory with the following code.,However an important thing to note is that the <Textbox> which has the rss feed link is binded to the source directly. The 'UpdateSourceTrigger' property is by default set to LostFocus(). I've changed it to 'PropertyChanged', so that when a user enters an rss feed, the bindings get updated. Also notice that 'BindsDirectlyToSource' is set to True. Another interesting feature is the Master-Detail binding. Notice that between Line numbers 53-63. The listbox's selection is binded to  description and link which are textblocks inside a stack panel. Now, when the listbox gets focus, we bind the frame's source to the uri in the texbox.

I've added some styles to the listbox aswell. all of which could be found in the source code. This surely is very simple and yet a foundation to write a powerful rss reader in wpf. :)

We could add more rss feeds, write value converters, validation rules etc. as required.


Window1.xaml

   1: <Window x:Class="RssReader.Window1"


   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"


   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"


   4:     Title="RssReader" Height="600" Width="800">


   5:     


   6:     <Window.Resources>


   7:     <XmlDataProvider x:Key="rssdata"


   8:                      Source="http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml"


   9:                      XPath="rss/channel/item"/>


  10:         


  11:     </Window.Resources>


  12:     


  13:     <DockPanel   DataContext="{Binding Source={StaticResource rssdata}}">


  14:         <StackPanel DockPanel.Dock="Top"


  15:                     TextElement.FontWeight="Bold" Background="Gray">


  16:         


  17:             <TextBlock Text="{Binding XPath=./../title}"


  18:                     FontSize="20" Margin="10 10 10 0"/>


  19:             


  20:             <TextBlock Text="{Binding XPath=./../description}"


  21:                     FontSize="10" FontWeight="Normal" Margin="10 0"/>


  22:             


  23:             <TextBox Margin="5" Text="{Binding Source={StaticResource rssdata},                             


  24:                                 BindsDirectlyToSource=True,


  25:                                 Path=Source,


  26:                                 UpdateSourceTrigger=PropertyChanged}"/>


  27:         </StackPanel>


  28:  


  29:         <StatusBar DockPanel.Dock="Bottom">


  30:             <StatusBarItem Content="{Binding XPath=title}"/>


  31:             <Separator/>


  32:             <StatusBarItem Content="{Binding XPath=pubDate}"/>


  33:         </StatusBar>


  34:  


  35:         <Grid>


  36:             <Grid.ColumnDefinitions>


  37:                 <ColumnDefinition Width="25*"/>


  38:                 <ColumnDefinition Width="75*"/>


  39:                 <ColumnDefinition/>


  40:             </Grid.ColumnDefinitions>


  41:            


  42:             <ListBox Grid.Column="0" IsSynchronizedWithCurrentItem="True"                     


  43:                      ItemsSource="{Binding}" DisplayMemberPath="title"


  44:                      Style="{StaticResource ListBoxHand}"/>


  45:             <GridSplitter/>


  46:             


  47:             <Grid Grid.Column="1">


  48:                 <Grid.RowDefinitions>


  49:                     <RowDefinition Height="Auto"> </RowDefinition>


  50:                     <RowDefinition Height="85*"> </RowDefinition>


  51:                 </Grid.RowDefinitions>


  52:  


  53:                 <ListBox x:Name="selection" Grid.Row="0" IsSynchronizedWithCurrentItem="True"                         


  54:                          Style="{StaticResource SimpleListBox}"


  55:                          VerticalAlignment="Stretch"


  56:                          GotFocus="selection_GotFocus">


  57:                              


  58:                     <StackPanel>


  59:                             <TextBlock Text="{Binding XPath=description}" />


  60:                             <TextBlock x:Name="txtlink" Text="{Binding XPath=link}"/>


  61:                         </StackPanel>


  62:                 </ListBox>


  63:                     <Frame x:Name="Explorer" Grid.Row="1"/>


  64:             </Grid>


  65:         </Grid>


  66:  


  67:       </DockPanel>


  68:     </Window>


  69:  




Window1.xaml.cs





   1: private void selection_GotFocus(object sender, RoutedEventArgs e) {


   2:   Uri uri = new Uri(this.txtlink.Text.ToString());


   3:   this.Explorer.Source = uri;


   4: }


   5:   




Screenie



rssreader_wpf


C0d3 : here

Sunday 24 August 2008

Behold!, Strategy Pattern will take care of it..!

We developers often have the common problem of programming the implementation and NOT the interface when we hurriedly develop software. Now, there are instances where 'test first code later' approach also might fail. This might happen when we misjudge the design issues and jump straight into what we want to achieve, but failing to consider issues like scalability, asking questions as to how easy will it be to accommodate changes in the future etc. Now, I believe, this is where experience comes for a cost !

Hmm.. until the day comes when your code needs to prove it's worth when changes or features are requested. It might seem rather easy at first until you start breaking feature after feature just by trying to add a tiny little feature.

Problems!!, After all, How would the world run without them!

Now, consider the following class hierarchy. I've taken a really trivial example here. The idea is to focus on the pattern and not on the problem!, remember we're building software that is ready for change in other words easily maintainable. maintenance is cost!.

ClassHeirarchy_Original

The abstract class 'Graph' has an abstract 'DrawGraph()' method. It also has a protected member List<int>> data. This is intended to be used by the DrawGraph() method. The abstract class also has implementations for SetUpGraphics(), which sets up the graphics device with double buffering mechanism let's say and a SetData() method which initialises the member variable 'data'.

The subclasses (sub-types: according to the design principle - sub class it iff the subclass is a subtype) PieGraph, LineGraph and BarGraph have their own implementations for 'DrawGraph()'. Each of which has it's own algorithm to draw the graph.

------------------------------------------------------------------------------------------------

For instance, the PieGraph's DrawGraph() method will draw a 360 degrees pie chart and map every value of data to an angle.

For example

data[0] maps to a 60 degrees spread.

data[1] maps to a 45 degrees spread and so on..

------------------------------------------------------------------------------------------------

The LineGraph's DrawGraph() method will draw a line graph indicating points on the xy-plane for every value of 'List<int>data'.

------------------------------------------------------------------------------------------------

The BarGraph's DrawGraph() method will draw a bar graph (column) for every value in 'List <int> data'. Let's also assume that it has flexibility to show graphs as columns or rows.

------------------------------------------------------------------------------------------------

It's clear that the 'DrawGraph()' method varies across all three implementations and every implementation has it's own algorithm. Now, Time to ask yourself questions.. Assume this structure has met the requirements and is working as expected. That's where most of us would stop the design and go home singing 'sweet home alabama', only to come back to it a few months later when we cannot escape the inevitable, CHANGE !!, It would be a new feature request by the client or porting it to a different platform, you never know, it's the business which grows and impacts the software or brings about change. (another favourite topic of mine ). Now, let's say you need to put in 3 new features

1] A mechanism to draw XY Axis scale dynamically.

Here X and Y unit values depend on a provided data set. Let's say the data set used to plot the graph are the values of used homes in the UK. ( in thousands) data set = {115.8,113,183.5,142.7,144.2,85.9,170.1,129.3}. Now, Given the data set, the graph should generate 8 Units on the X-Axis and a proportionate scale on Y-Axis (0-200 would be fine in this case).

2] Calculate Range,Variance and Standard Deviation of the data set.

3] Users should be able to resize the graph dynamically - Automating Scaling.

Ok,let's start reworking our class structure to add these features.

Let's start with feature 1]. Auto generating Units for XY based on Data. By looking at the structure, It's very clear that by adding a method in Graph Class (Virtual Method), the classes LineGraph and BarGraph can override it and implement automatic generating of XY units. But what would happen to PieGraph ?. It will have to do nothing. In other words, override to give no implementation.

PieGraph.AutoGenerateXYUnits() { //no implementation }

Now, to overcome this **side effect ** , we can think of sub classing LineGraph and BarGraph further. i.e, it can be derived from a class called CordinateGraph. CoordinateGraph derives from Graph. AutoGenerating XY Units feature can then be implemented in the Co-ordinateGraph class as a virtual method. So that it can be overridden in the LineGraph and BarGraph Classes. Notice as we try to do such modifications, the behaviours become very tightly coupled to it's implementations and it will eventually become harder and harder to maintain such code simply because adding a feature to the base class Graph will break the system, introduce side effects as we saw above.

Ok,

How about 'interfacing' the AutoScaleXYUnit behaviour ?. This might sound interesting as only the required classes implement the behaviour.

ClassHeirarchy_Mod1

But, notice carefully, you will have to repeat implementations for all the classes which implements the IAutoGenXYUnits interface. Lets say in the future, if there were to arise a situation where 10 different classes need to implement this behaviour , then there will be 10 implementations, and you introduced another maintenance nightmare.. no code reuse. I'll come back to this.

Think of the possible implementations for feature 2] Calculating Range,Variance and Standard Deviation for the data set. It could be a very straight forward implementation. add it to the base class {as a feature} ?, Yes, it would do the job for all the 3 Subclasses and if the method is virtual, it would be even better. Let's agree that this is pretty straight forward virtual method implementation in the Class 'Graph'. (and it would do it's job )

And finally, possible implementations for 3] Automatic scaling of the graph at runtime. This behaviour varies across all there sub classes. If you were to think that adding a method to scale the graph in the Graph Class would be sufficient. What if PieChart needed no scaling at all ? , LineGraph and BarGraph needed vertical and horizontal scaling respectively ?, Side effects would occur, code would break..

A good solution to 1] and 3] would be to use the strategy pattern. Some general design principles that I've considered when re factoring this to use a strategy pattern. And most of them would work for behavioural patterns***

- The open closed principle: open to extension but closed for modification.

- Program the interface

- Use Composition over inheritance

- Cohesion

- Tight coupling vs Loose coupling

Caution: It might be argued that some of the design principles do not apply to every kind of a problem. For e.g. Huge Enterprise Applications with millions of users. See Enterprise Application Patterns. Here, the design would primarily focus on issues like Scalable architecture, Service oriented design, concurrency, minimizing round trips to the server etc. and it can be noticed that what seems a perfect solution for a stand alone app might be dreadful and disastrous one for Enterprise Apps.

Identifying what 'changes' and what 'remains'. A general trick is to encapsulate what changes and keep what stays. The Draw method clearly varies across all three implementations. So, Let's make a 'IDrawable' interface out of it. Similarly for scaling the graphs dynamically, we could think of an 'IScalable' interface. We go ahead and provide concrete implementations to them. The concrete implementations to the IDrawable interface would be

--o IDrawable { DrawBar, DrawLine , DrawPoint, DrawPie }, This also takes care of feature request 1]. Similarly, the IScalable would have

--o IScalable { VScale, HScale, VHScale, NoScale } concrete implementations. Now, We can add the interface references to the 'Graph' class so that the classes BarGraph, LineGraph and PieGraph are free to chose their implementations dynamically at runtime. Cool innit ? . ( This is the open closed principle). We are giving the interface, but not the modifiable implementation to the 'Graph' class.

The strategy pattern oriented solution will look like the following.

The IScalable interface and it's concrete implementations

IScalable

The IDrawable and it's concrete implementations

IDrawable

The Graph Class hierarchy

MainClasses

The Final Solution

Strategy

The conclusion.

------------------------------------------------------------------------------------------------

I'll leave the Pros and Cons to the reader to decide and evaluate. But the strategy pattern's promise for sure is that it will allow your algorithms to evolve independently of your main class hierarchy. So there won't be any side effects or breaking up of the hierarchy.

------------------------------------------------------------------------------------------------

Finally some generalizations..

------------------------------------------------------------------------------------------------

If you are not inviting change, I'm sure you're not in software development. This is where experience comes for a cost!!! it counts where it matters most!!! I've always felt there are 2 kind of developers in this world. Developers who know what to do AND the incapable or often 'confused' mutts. The incapable mutts fall into a zillion multi-disciplinary categories. So, think of the design principles while writing or re factoring code. Keep it flexible, easy to maintain and above all watch out for patterns.

------------------------------------------------------------------------------------------------

*** Behavioural Patterns: Patterns that are most concerned with communication between objects. They are also concerned with encapsulating behaviours in an object and delegating requests to it.

------------------------------------------------------------------------------------------------

Some Links:

1] A claim that Java's extend is evil

2] Classes in the .NET BCL. Also take a look at .NET 3.5 LINQ Classes.

3] Java 2 API: Take a look at Line,Line2D.Double and Line2D.Float Classes. A more comprehensive study (to make life hell) would be to consider

java.lang.Object

-java.util.AbstractCollection

-java.util.AbstractList

-java.util.AbstractSequentialList

- java.util.LinkedList

SourceCode: Here

Comments / Criticisms / Discussions are welcome.

Friday 25 July 2008

Designing an Enumerator for Business Objects

Following is my elegant enumerator design which can be used for enumerating business objects from the database. Designing an enumerator with C#, .Net 3.5 will be much more elegant simply because of LINQ and LINQ to SQL. I will write about it in my future posts. LINQ has made it extremely easy to do such things, and i will prove my point in the future posts. This is also mostly based on Enterprise patterns (Check out the most famous Martin Fowler's book) . I've used a Table Gateway and a normal Iterator pattern.

BusinessObjectEnumerator

 

Product - Business Object

Product.cs

public class Product
{
int id;

public int Id {
get {
return id;
}
set {
id = value;
}
}
string name;

public string Name {
get {
return name;
}
set {
name = value;
}
}
double price;

public double Price {
get {
return price;
}
set {
price = value;
}
}

public override bool Equals(object obj) {
if (null==obj)
return false;
else
{
Product p = obj as Product;
return (p.id == this.id);
}
}

public override int GetHashCode() {
return id.GetHashCode();
}

public override string ToString() {
return name.ToString();
}



 



DBEnumerator.cs



    public abstract class DBEnumerator<T>:IEnumerator,IEnumerable
{
private int position;
protected List<T> list;
protected TableGateway tablegateway;
protected abstract void Read(string sql);
public virtual void Add(T item) {
if (!list.Contains(item))
{
list.Add(item);
}
}

#region IEnumerable Members

public IEnumerator GetEnumerator() {
return (IEnumerator)this;
}

#endregion

#region IEnumerator Members

public object Current {
get {
return (object)list[position];
}
}

public bool MoveNext() {
position++;
return (position < list.Count);
}

public void Reset() {
position = -1;
}

#endregion
}



ProductEnumerator.cs



    public class ProductEnumerator:DBEnumerator<Product>
{
public ProductEnumerator(string sql) {
this.tablegateway = new TableGateway();
this.list = new List<Product>();
Read(sql);
this.Reset();
}

internal TableGateway TableGateway {
get {
return tablegateway;
}
}

protected override void Read(string sql) {
DataTable dt = new DataTable();
dt = tablegateway.ExecuteNonQuery(sql);
foreach (DataRow row in dt.Rows)
{
Product p = new Product();
p.Id = Convert.ToInt32(row["Id"].ToString());
p.Name = row["Name"].ToString();
p.Price = Convert.ToDouble(row["Price"].ToString());
Add(p);
}
}
}



TableGateway.cs



   public class TableGateway
{
private string connstring;
private IDbCommand command;
private Collection<IDataParameter> parameters;

public TableGateway() {
connstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Projects\\C#Projects"+
"\\BusinessObjectEnumerator\\Inventory.mdb;";
parameters = new Collection<IDataParameter>();
}

public void AddParameters(string parameterName, string parameterValue) {
IDataParameter param = command.CreateParameter();
param.ParameterName = parameterName;
param.Value = parameterValue;
}


public string TableName{
get {return "Tablegateway";}
}

public DataTable ExecuteNonQuery(string sql)
{
using (IDbConnection conn = GetConnection())
{
command = conn.CreateCommand();
foreach (IDataParameter param in parameters){
command.Parameters.Add(param);
}

OleDbDataAdapter oledbdataadapter = new OleDbDataAdapter(sql,(OleDbConnection) conn);
DataSet dataset = new DataSet();
try
{
oledbdataadapter.Fill(dataset, this.TableName);
}
catch
{
throw;

}
finally
{
conn.Close();
}
return dataset.Tables[TableName];
}
}

private IDbConnection GetConnection() {
return new OleDbConnection(connstring);
}

}



Putting the ProductEnumerator to test



  static void Main(string[] args) {

ProductEnumerator myproducts = new ProductEnumerator ("select * from products");

Console.WriteLine("Enumerating products..\n");

foreach (Product p in myproducts){
Console.WriteLine("ID: ,"+p.Id+
"Name: ,"+ p.Name+
"Price: ,"+p.Price);
}

Console.WriteLine("\nPress any key to exit..");
Console.ReadKey();
}



Notice, Since we have implemented the IEnumerable and IEnumerator interfaces, we can use the ProductEnumerator in a foreach statement. This will be the cool part of Enumerators. The MSIL generation for the foreach statement would do something like the following:



IEnumerator ienum = myproducts.GetEnumerator();



while(ienum.MoveNext()) {



...



}



Also, We can  provide mechanisms to add stuff into the List<T> of the DBEnumerator. By doing this we will need to have some mechanisms to persist the newly added object to the DB. In other words instantaneously serialize the object. This will require some kind of an EventHandler to track the List<T> added event. Hmm... reminds me of a 1000 patterns from Martin Fowler , just to do this.. :) (Oh, my brave attempt to write a DataMapper in 3 days, i paid the price in the ACW..Thanks to Dr.Grey for enlightening me about my deed)



Output



Enumerating products..



ID: ,1Name: ,Product APrice: ,10.99

ID: ,2Name: ,Product BPrice: ,12.99


ID: ,3Name: ,Product CPrice: ,10.99


ID: ,4Name: ,Product DPrice: ,14.99


ID: ,5Name: ,Product EPrice: ,19


ID: ,6Name: ,Product FPrice: ,19.99


ID: ,7Name: ,Product GPrice: ,7.99


ID: ,8Name: ,Product HPrice: ,5.45


ID: ,9Name: ,Product IPrice: ,3.44


ID: ,10Name: ,Product JPrice: ,0.99



Press any key to exit..



The DB (for proof)



image



Sunday 15 June 2008

Asynchrounous Programming Introduction

Coming soon..
Just reminding myself that i have a pending post on asynchronous programming in .net tonight..Just working on some samples at the moment. :D It's exciting!!

Tuesday 10 June 2008

Discovering Patterns in .Net BCL and ASP.Net

Patterns behind the scenes in .Net and ASP.Net

I just found this great article on MSDN which enlightens the .Net programmer about the patterns used in .Net BCL and ASP.Net. The link to this great article can be found here.

The Decorator Pattern Part I

The Need for the Decorator Pattern:

Decorators can be used to decorate classes at runtime using a form of object composition.This is a good pattern which helps to minimize overuse of inheritance for adding special behaviours to classes. Decorators are primarily used to add flexibility to design. They are used to add more behaviours to existing classes by adding a wrapper around them,without changing the existing code. One needs to be careful in writing a decorator. Too much decoration can make the code lousy,difficult to read,modify and maintain. For instance, consider Java's I/O libraries. They are notoriously difficult for people to understand at first. But if they just saw the classes as a set of wrappers around the abstract class InputStream, life would be simpler..

Learning by example..

1. Recognising the decorators from the Java.IO classes

Decorator1

The InputStream is the abstract component. The FilterInputStream, ByteArrayInputStream, StringBufferInputStream and the FileInputStream are abstract decorators.

Now, PushbackInputStream, BufferedInputStream, DataInputStream and LineNumberInputStream are all concrete decorators.

Now, think about the decorators and the flexibility it adds to the design of Java.IO in the following sentences..(Classes are open for extension but closed for modification)

InputStream in = new BufferedInputStream(new FileInputStream("aFile.txt"));

BufferedInputStream bis =  new BufferedInputStream ( new DataInputStream ( new FileInputStream ( "aFile.txt" )  )  ) ;

 

2. An example of decorating our beverage component by using an abstract decorator 'CondimentDecorator' and a single concrete decorator 'Mocha'. The concrete components add specialized classes (HouseBlend, Espreso). We will see this in more detail in Part II. Consider the following class diagram.

 

image

The Beverage is the component which we are interested in decorating here. The CondimentDecorator is the abstract decorator. The Classes Expresso and HouseBlend are concrete components. The Mocha class is a concrete decorator.

Now, look at the following code to understand the power of concrete decorators and the Decorator Pattern itself.

Beverage b1 = new Espresso();      // A type of Beverage, Concrete component

Beverage b2 = new HouseBlend(); //A type of Beverage, Concrete component

b2 = new Mocha(b2); //wrap the beverage with Mocha

 

Decorators Rule!, More reasons and justifications in Part II..