Maternal Pro

What I’ve been working on for the last four months

The last four months I’ve been the main developer / architect of a medical project called Maternal PRO, a documentation system for Gynecology and obstetrics which was presented at the 11th Gynecology Conference at the Hilton hotel in Athens, Greece from 28/5/2009 to 31/5/2009.

Maternal was built on .Net Framework 3.5 SP1, it’s database agnostic(single user version uses a Sql Server 2005/2008 Express database with a Linq2Sql database layer) and has a 100% WPF UI.

How did I end up developing Maternal

Right after the start of 2009 (and a very successful past year) I was trying to establish my place somewhat more as a freelancer in the Greek IT market so I ended up writing a tech CV and sending it to the HR departments of some companies. One of those companies was NOON. After the initial interview I immediately started working for them on the project.

NOON is really a cool place to work. Developers do have the flexibility to choose the tools they need in order to perform specific tasks and we also have the flexibility to try out cool new technologies (like WPF and Silverlight) and integrate them into our projects.

We are not a Microsoft oriented company. My department might be but there are people here working with Java (mobile applications like Gynofone – which is like a Maternal lite version for Java based phones), others that work with Flash. We even have COBOL & PHP developers.

What the future looks like

Maternal was my first project while working for NOON. It’s left a bittersweet taste because of the pressed deadline but I’m happy to have worked on it: I’m happy to have architected it and I’m proud to say that I did.

In the near future I might start developing a WPF Reporting engine. An end-user reporting toolkit that can be bundled with any .Net application that will be dependent on the business layer of the application and not the data repository.

I’m eager to start working on this project, I’ve been thinking of ways to develop it for the last 2-3 years and I might even start working on .Net 4.0 on that project.

So, that’s what’s been going on lately, that’s why the blog is not getting updated as much as I’d like and that’s what’s going to happen (hopefully) in the near future.

Write to you later,


I’m not dead, just busy

It’s been ages since the last post on my blog. The reason for that misfortune is that I took on a project for a new client that is really time-consuming and has an impossible deadline. That’s the bad news.

The good news is that the project I’m working on got me in the beautiful world of WPF (finally). I know that the majority of developers aren’t convinced that WPF makes sense yet but what I realized in the past 3 months that I’ve been intensely working with it, is that WPF can be a life saver!

Right after April (that’s when my part in the project will be complete) I’ll make a strong comeback with blog posts. I’ve already made my mind on the post subjects and boy-oh-boy-do-I-have-material-to-work-with!

I won’t go into much detail now but you should be expecting posts on ASP.NET MVC, WPF (although not an expert I’ve found some tricks that could make your life easier) and LINQ & Entity Framework.

Till then,
Keep coding


how to fix apps that stop after some time on windows azure

Recently I uploaded one of my web apps to Windows Azure. After the publish everything seemed to work alright but the next day, when I tried to view the app, it wouldn't start. I got some weird page null error and nothing else.

step 0: what makes sense

My first guess was that I had done something wrong, that some sort of exception was being thrown that Azure wouldn't let me see but after reviewing the logs I realized that no exceptions whatsoever had occurred.

step 1: what doesn't make sense

Since the above scenario wasn't the case and since the only reasonable explanation I could think of was that the web app after it's first stop (like regular IIS web apps stop after some period of inactivity) wouldn't start again (for some peculiar reason).

step 2: the solution

The solution (that seems to work for me) is simple and took just 17 or so lines of code: I added a new Worker Role to the solution that every minute makes a HttpWebRequest to the applications index page making sure that the app never stops because of inactivity.

This is the code I used:

public override void Start( )
{
	RoleManager.WriteToLog( "Information", "Worker Process entry point called." );
    
	while ( true )
    {
	    RoleManager.WriteToLog( "Information", "Working" );
    
		try
	    {
    		HttpWebRequest rq = HttpWebRequest.Create("http://path/to/your/web/root" ) as HttpWebRequest;

			WebResponse rs = rq.GetResponse( );
	        rs.Close( );
    	}
	    catch ( Exception )
    	{
    		RoleManager.WriteToLog( "Information", "Could not reach http://path/to/your/web/root" );
	    }

		RoleManager.WriteToLog( "Information", "Sleeping" );

        Thread.Sleep( 60000 );
	}
}

If you are experiencing similar problems I hope this may be of use to you.


The Mac candy

Today I had one of those new iMacs sent to me from a friend in order to repair something that didn't really need any fixing (I know, Macs never need fixing).

Anyway, as I'm going to have the Mac at my place for today and tomorrow, I started *using* it for more than text and photo editing so I got TextMate working, MySql up and Rails (Ruby is pre-installed so just gem install rails --include dependencies) and I started creating a new rails project.

I knew TextMate is a powerful development utility (more like a dev Swiss knife) since I've used it more than occasionally in the past I never developed any rails projects with it and what hit me at the time was how fast the whole thing started to come alive.

TextMate + Rails seems like a perfect match to me no matter what others may have to say, not to mention the Mac eye-candy that really makes my day whenever I happen to use one.

Two to three hours after that I found myself surfing a local e-commerce site (Greece doesn't have a big market for Macs - cry :() trying to find out how much would it cost me to get one for myself and believe me when I say that the "Express Checkout" button seemed really sexy at that point.

Despite the fact I didn't buy a Mac for myself (yet), days like these make me wonder: "Why oh why don't we (Greeks) have a development market in which Macs could be an option for our workstations?".


2009 > 2008

In a few hours we'll say goodbye to 2008 and welcome 2009 and everyone all around the globe seems anxious to experience the first moments of 2009 in the best possible way.

There are those amongst us that have declared their new year's resolutions and others that haven't yet but what strikes me in this moments of joy is that there are some of us who won't have a chance to do so or won't even bother.

As we are all going to pay our respects to 2008 and celebrate the birth of the new year there are people getting bombed, people who are starving and people who have absolutely no clue on how they are going to survive one more year.

My hopes are high for 2009... My hopes are sky-high but hopes are just that: "the general feeling that some desire will be fulfilled". They are just a feeling. Hoping without working towards what you aim for never got anyone where they needed to be.

2009 smells of change: Change in politics, change in economics, change even in the way we change things and our world desperately needs to change but not (once again) for the worst but for the better.

May the new year bring you what 2008 wouldn't. May health, joy and love come to you in a way you never before imagined that could exist and may 2009 be the best year of your life yet.

Happy new year!


embedding Sql server compact 3.5 sp1 in your application for both x32 and x64 systems

Having Sql Server Compact 3.5 SP1 embedded in your application for both x32 and x64 systems is really easy and a life saver. I took some screenshots that will guide you through the whole process. Enjoy.

step 0: creating the X86 and AMD64 folders

When your application tries to access Sql Server Compact it first looks whether its dlls exist into the application's directory into 2 specific folders: the X86 and AMD64 folder (for x32 and x64 versions respectively). So, create those 2 folders first.

If your system is x64 and inside the AMD64 folder you've placed the Sql Server Compact dlls then your application will choose that directory by default for you (an easy performance gain).

00. Create folders

step 1: adding Sql server compact's dlls to your application

All of the Sql Server Compact Edition components that your application *may* use are defined in 7 dlls that can be found into the Sql Server Compact installation on your development machine (perhaps you can narrow it down to 3-4 dlls depending on what exactly you need from SqlCe but for this example I'll add them all).

In my machine I've installed both the x32 and x64 versions of Sql Server Compact 3.5 so I have all the dlls I need for both platforms.

Bellow can see some screenshots I took while adding the x64 dlls to my project.

01. Add files AMD64

02. Select AMD64 Files

The dlls I selected correspond to the x64 version of Sql Server Compact. For the x32 dlls you have to look in the x32 program files folder.

After adding the dlls to your project it's important to select them again and set the "Build Action" to "Content" and the "Copy to Output" property to "Copy always" or "Copy if newer" so that these files are indeed copied to the application directory.

03. Copy Local AMD64

Repeat the above steps but this time place the dlls into the X86 folder and get them from the x32 installation directory of Sql Server Compact.

Last but not least, we have to add the first (and only) reference to our project for System.Data.SqlServerCe and set its "Copy Local" property to "True".

04. Add SqlCe Reference

That's it. The last screenshot is what the complete project looks like (with all the references).

07. Final

Last minute note: If you are using ClickOnce, remember to remove the pre-requisite for Sql Server Compact before you deploy, if you leave that single checkbox checked you defeat the purpose of having Sql Server Compact embedded to your app.

Keep coding and If I don't post anything more till the new year:

"May 2009 be what 2008 wasn't"


strings, hex and byte arrays

I'll post a couple of method extensions I often use in my projects:

The first one is a function that, given a byte array, converts it to a string hex representation and the second transforms a hex representation string to it's original byte array.

public static string ToHexString( this byte[] bytes )
{
	if ( bytes == null ) return ( string )null;

	string ret = string.Empty;

	foreach ( byte b in bytes )
		ret += b.ToString( "x2" );

	return ret;
}
public static byte[] ToHexArray( this string str )
{
	if ( string.IsNullOrEmpty( str ) )
		return new byte[] { };

	if ( str.Length % 2 != 0 )
		return new byte[] { };

	int byteLength = str.Length / 2;
    byte[] ret = new byte[byteLength];
    int j = 0;
    
	for ( int i = 0; i < str.Length; i += 2 )
    {
    	string hex = str.Substring( i, 2 );
        ret[j] = byte.Parse( hex, System.Globalization.NumberStyles.HexNumber );
        j++;
	}

	return ret;

}

Now that I think of it I'll post also a third method extension that determines whether a string is indeed a hex representation.

public static bool IsValidHexString( this string str )
{
	if ( string.IsNullOrEmpty( str ) ) return false;

	if ( string.Length % 2 != 0)
		return false;

	string map = "0123456789abcdef";	

	foreach ( char c in str.ToLower( ) )
		if ( !map.Contains( c ) )
			return false;

	return true;
}

I really hope these 3 extensions will be of use to you one day :)

Till the next post, keep coding.


world of warcraft: wrath of the lich king - the phenomenon continues

wrath Blizzard's second World Of WarCraft expansion pack, Wrath of the Lich King, reached it's release date. Indeed it's the thirteenth day of November 2008 and all around the globe the noise has already started as millions of active subscribers will rush to the nearest retail store to buy the new expansion.

I myself am a former World Of WarCraft player. I've been a WoW player since the beta and it wasn't until recently that I decided to stop playing but the scent of this day, the aroma of the anxiety make me remember past glories in nostalgia.

World of WarCraft is the phenomenon of our time: The first MMORPG that captured more than 10 million subscribers (or is it 11 by now?), a game with a community that never seizes to amaze me and a game that brought people from all around the globe together.

Having said that, I'd like to congratulate every single Wrath player and wish them good luck in their new adventures in Wrath of the Lich King.


The power of interface polymorphism

The problem

Apparently there are lots of developers out there that don't exactly know (or haven't actually thought of) how to separate their data access layer from the business or even the presentation layer in their projects and always get into trouble when they have to insert something new into their DAL or Business Layer.

For about two weeks now I've been developing a new blog engine based on ASP.NET MVC (BETA) and I was wondering how I could make it database independent because I would like the engine to be able to use XML files as the backend, Sql Server 2005, MySql or even Oracle if needed.

This post will explain the simple solution I rely on to make my project backend-agnostic. The code here will be oversimplified. If you'd like to have a look at what I'm building send me an email via the contact link and perhaps I'll send you something when I reach the next milestone.

Having determined the project's needs I realized that my presentation layer should be agnostic of the database access (which is indeed the best way to develop anyway).

Step 0: Defining the data access layer's functionality

Considering what a really simple - probably a  baby like - blog engine does these days I designed an interface that met my simple needs.

using System;
using System.Collections.Generic;

using Blog.Models;

namespace Blog.DataAcessLayer
{
    public interface IBlog
    {
        Post GetPostById( int Id );
        List<Post> GetIndexPosts( );
    }
}

This interface will be the only way the rest of the project (my controllers that is - remember? it's an ASP.NET MVC Project) can communicate with the underlying data source.

Step 1: Creating the data access layer factory

The way the blog engine understands where the underlying data source exists and what type of data source (XML, MySql, Sql Express, etc) we've chosen to use is though the connectionStrings setting in the Web.config file.

<connectionStrings>
	<add name="Db" connectionString="Data Source=localhost;Initial Catalog=blog;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>  

What this connection string entry (Db) really says to the application is that I'm using a connection whose provider is the System.Data.SqlClient namespace with the specified connection string value. Easy right? Indeed.

Next, we'll create factory that can give us (when invoked) the appropriate data access layer implementation.

using System;
using System.Configuration;

namespace Blog.DataAcessLayer
{
    internal static class BlogFactory
    {
        public static IBlog GetNewBlog( )
        {
            string connectionString = ConfigurationManager.ConnectionStrings["Db"].ConnectionString;
            string providerName = ConfigurationManager.ConnectionStrings["Db"].ProviderName;

            if ( providerName == "System.Data.SqlClient" )
                return new Providers.SqlServerProvider( connectionString );
            /*
            else if ( providerName == "MySql" )
                return new Providers.MySqlProvider( connectionString );
            else if ( providerName == "Xml" )
                return new Providers.XmlProvider( connectionString );
            else if ( providerName == "Oracle" )
                return new Providers.OracleProvider( connectionString );
            */
            else
                return ( IBlog )null;
        }
    }
}

Step 2: Implementing a provider

What we need next is to implement a provider so you can get an idea of what's going on. I'm going to give you head start on the SqlServerProvider.

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;

using Blog.Models;
using Blog.DataAcessLayer;

namespace Blog.DataAcessLayer.Providers
{
    internal class SqlServerProvider : IBlog
    {
        #region [ Properties ]

        private string ConnectionString { get; set; }

        #endregion

        #region [ Constructor ]

        public SqlServerProvider( string ConnectionString )
        {
            this.ConnectionString = ConnectionString;
        }

        #endregion

        #region [ Interface Implementation ]

        public Post GetPostById( int PostId )
        {
            Post ret = null;

            using ( SqlConnection cnn = GetConnection( ) )
            {
                SqlCommand cmd = cnn.CreateCommand( );
                cmd.CommandText = "p_GetPostById";
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.AddWithValue( "@PostId", PostId );

                using ( SqlDataReader reader = cmd.ExecuteReader( ) )
                {
                    if ( reader.Read( ) )
                    {
                        ret = new Post( );
                        ret.PostId = ( int )reader["PostId"];
                        ret.Title = ( string )reader["Title"];
                        ret.Body = ( string )reader["Body"];
                        ret.Author = ( string )reader["Author"];
                        ret.DateSubmitted = ( DateTime )reader["DateSubmitted"];
                    }

                    reader.Close( );
                }

                cnn.Close( );
            }

            return ret;
        }

        public List<Post> GetIndexPosts( )
        {
            List<Post> ret = new List<Post>( );

            using ( SqlConnection cnn = GetConnection( ) )
            {
                SqlCommand cmd = cnn.CreateCommand( );
                cmd.CommandText = "p_GetIndexPosts";
                cmd.CommandType = CommandType.StoredProcedure;

                using ( SqlDataReader reader = cmd.ExecuteReader( ) )
                {
                   while ( reader.Read( ) )
                    {
                        Post p = new Post( );

                        p.Author = ( string )reader["Author"];
                        p.DateSubmitted = ( DateTime )reader["DateSubmitted"];
                        p.Body = ( string )reader["Body"];
                        p.PostId = ( int )reader["PostId"];
                        p.Title = ( string )reader["Title"];

                        ret.Add( p );
                    }

                    reader.Close( );
                }

                cnn.Close( );
            }

            return ret;
        }

        #endregion

        #region [ Helpers ]

        private SqlConnection GetConnection( )
        {
            SqlConnection cnn = new SqlConnection( this.ConnectionString );
            cnn.Open( );

            return cnn;
        }

        #endregion
    }
} 

Step 3: What does our database look like?

Normally, the database should have been created first but this is not a real world example so I'll just provide a simple script you can use to create your database (this is a Sql Server 2005 script):

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [Post](
	[PostId] [int] IDENTITY(1,1) NOT NULL,
	[Title] [nvarchar](400) NOT NULL,
	[Body] [ntext] NOT NULL,
	[Author] [nvarchar](40) NOT NULL,
	[DateSubmitted] [datetime] NOT NULL CONSTRAINT [DF_Post_DateSubmitted]  DEFAULT (getdate()),
 CONSTRAINT [PK_Post] PRIMARY KEY CLUSTERED 
(
	[PostId] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [p_GetPostById]
	@PostId int
AS
BEGIN

	SET NOCOUNT ON;

	SELECT
		*
	FROM Post
	WHERE
	( PostId = @PostId )

END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [p_GetIndexPosts]
AS
BEGIN

	SET NOCOUNT ON;

	SELECT TOP 10
		*
	FROM Post
	ORDER BY DateSubmitted DESC

END

After creating the database, remember to update the connection string to the one that suits your installation.

Lets define our Post object now:

using System;

namespace Blog.Models
{
    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Body { get; set; }
        public string Author { get; set; }
        public DateTime DateSubmitted { get; set; }
    }
}

Step 4: Getting the data access to our controllers.

Since the controllers in ASP.NET MVC can inherit from base classes (we are after all using .Net aren't we?) wouldn't it be cool not to have to write the same stuff over an over again till the end of time? Please! someone argue that!

Lets define a base controller for our application:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.UI;

using Blog.DataAcessLayer;

namespace Blog.Controllers
{
    [HandleError]
    [OutputCache( Location = OutputCacheLocation.None )]
    public abstract class ControllerBase : Controller
    {
        #region [ Properties ]

        private IBlog __blog;

        #endregion

        #region [ Constructor ]

        protected ControllerBase( ) : base( ) { }

        #endregion

        #region [ Properties ]

        protected IBlog Blog
        {
            get
            {
                if ( __blog == null )
                    __blog = BlogFactory.GetNewBlog( );

                return __blog;
            }
        }

        #endregion
    }
}

Now that this is done, lets implement the HomeController (front page controller for our blog):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

namespace Blog.Controllers
{
    public class HomeController : ControllerBase
    {
        public ActionResult Index( )
        {
            return View( Blog.GetIndexPosts( ) );
        }

        public ActionResult Entry( int id )
        {
            return View( Blog.GetPostById( id ) );
        }
    }
}

Last and final step is to define our ASP.Net MVC Views, we'll just need 2 for this example (one for the blogs front page and one for the permalink of each post):

Index View (front page):

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="Blog.Views.Home.Index" %>

<%@ Import Namespace="Blog.Models" %>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <% foreach( Post p in ViewData.Model) { %>
    
        <h2><%= Html.Encode( p.Title ) %></h2>
    
        <p><%= Html.Encode( p.Body ) %></p>
        <%
            string permalinkUrl = Url.Action( "Entry", "Home", new { id = p.PostId } );
            string author = Html.Encode( p.Author );
            string timeStamp = p.DateSubmitted.ToUniversalTime( ).ToString("dd/MM/yyyy HH:mm");
        %>
        <small>
            <%= author %> | <%= timeStamp %> UTC | <a href="<%= permalinkUrl %>" title="Permalink">Permalink</a>
        </small>
    
    <% } %>
</asp:Content>

Entry View (permalink):

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Entry.aspx.cs" Inherits="Blog.Views.Home.Entry" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
    
    <% if( ViewData.Model == null ) { %>
    
        <h1>The post was not found!</h1>
        
    <% } else { %>
        
            <h2><%= Html.Encode( ViewData.Model.Title ) %></h2>
        
            <p><%= Html.Encode( ViewData.Model.Body )%></p>
            <%
                string permalinkUrl = Url.Action( "Entry", "Home", new { id = ViewData.Model.PostId } );
                string author = Html.Encode( ViewData.Model.Author );
                string timeStamp = ViewData.Model.DateSubmitted.ToUniversalTime( ).ToString( "dd/MM/yyyy HH:mm" );
                string indexUri = Url.Action( "Index", "Home" );
            %>
            
            <small>
                <%= author %> | <%= timeStamp %> UTC | <a href="<%= permalinkUrl %>" title="Permalink">Permalink</a>
                <br />
                <a href="<%= indexUri %>" title="Back to index">Back to the blog's index</a>
            </small>
    
    <% } %>
    
</asp:Content>

Step 5: Putting it all together

For your convenience I've uploaded the full source code (the link is provided below) - written in Visual Studio 2008. You should need ASP.NET MVC (BETA) installed for it to launch.

I hope I gave you something to think about, your comments are always welcome.

DALInterfaces.zip (278.67 kb)


Blog alive

Welcome to my new blog. I sincerely hope that every single bit of information posted here will be of use to you but even if that's not the case I sure hope I'll at least be able to make you smile.

Till the first true post,
Bye bye.


Something useful (hopefully)

micro-blogging

@twitter: azazeal

Search

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my my associates' or empoyers' view in anyway.