Saturday, May 22, 2010

The First One

So, I have re-named the data structures.  I used the database project template in Visual Studio 2010, and to be honest I wasn’t impressed. As a database management project tool, I found it almost impossible to commit the updated changes back to the database.

But first, let me look at what I did and what I liked and what I didn’t like at each step.  My first step was to use a clean install of the project and get that imported into the database project.  That worked pretty well.  It created one file for each database object (stored procedure, table etc.) which I thought was great.  It created a good structure which was pretty easy to understand (for a non DBA like me).

VS2010 SQL Project FolderStructure

To me, this structure is very similar to the structure that you see in the MS SQL Studio, which is a good thing in my mind.

Then I did one of the items on my version 2 list for the project, to rename the database tables.  The refactoring was very much in line with the way code gets refactored in VS2010.  It was quick and easy, and every reference was renamed.  Needless to say I did like that.

Now to the parts I didn't like.  I wanted to set one of the tables to save the data within as it was part of the project, not the dynamic data of the system usage. I could not work out how to do this.  I would have thought that a database project would have been able to allocate some default data to the tables, if not mark some tables as having all their data from the project loaded into the implementation of the project.

This leads to my next problem.  I got the source data structure from a database.  I made a relatively simple if somewhat extensive change.  I then wanted to update the database with the changes and it would not update.  Kept on returning a user error or something.  I am going to be honest here.  This to me is the core of a database project.  Writing scripts is one thing.  The ability to use a GUI to manage the code is awesome.  The UX for updating the data structures is not.

As a result, at this time I am not going to use the database project for my changes.  At least until I am able to resolve the 2 issues that I have encountered so far.  So, at this stage I have renamed the database tables, and am about to tackle another of the items on the list.

Sunday, May 16, 2010

Audit Again

So, I am reviewing the audit code that I have written.  Following the review of some posts by a friend, I am going to write the next version of the audit functionality that I finished a while back (a whole 2-4 weeks). So, using that as a basis, and ensuring that I maintain the aims set out in the previous version (for a refresher, go here).

Now, the aims for the next version are as follows:

  • Process logging, not just a generic log table, but one that is based on each process so that the logging system can differentiate between 2 processes running at the same time.  Also increased logging for better debugging of issues.
  • Allowing for the core parts of the audit to be in the line of business database, but still archiving to a separate database.  The audit should be configurable so that it can either run out of the archive database or the line of business database, or both (where the business has 2 audited databases there should only be one archive database).
  • Rename the data objects so that they make logical sense.
  • Further refractor the code so that there are as many re-usable parts as possible.
  • Use the 2010 Visual Studio 2008 Database solution template to write the code in.

That is all I can think of as improvements for now.  If I think of anything else that I would like to add to the next version, I will let you know.

Saturday, May 15, 2010

A Breath Before the Start

Well, I had a friend look at my blog the other day. He is someone who I respect in the technical world, knows heaps, and is just an all round good guy.  (For those wondering, the man is Richard Banks, who you can find here.  He is also worth a follow on twitter, over here.) Anyway, he pointed out some spelling and grammar issues, which I was expecting.  He also gave me some tips and tricks for blogging, like the code colouring and where I can host files without any ads, which I will incorporate I to my last few posts.  I'm not going to tidy every post, just the last two. Hope to do that this weekend.

Then he ended his advice with a “but”. He wanted to know why I was looking at using prefixes on table names, and my thoughts on a "decoupled" application. And he recommended that I review some other patterns, such as the repository pattern. Taking this advice, I did some searching on the web to look into the repository pattern, and as he suggested I reviewed my thoughts and the post content.  Following this, I have decided that he is right (as he usually is).

As a result, I am going to make some changes to my approach.  Firstly, I am going to write an updated version of my audit code.  One without named prefixes, that makes more sense with regards to naming conventions.  (As you can see I am dropping the prefix naming convention on the data layer.)

Secondly, I am going to write a decoupled application in the correctly.  One that has it’s layers decoupled, not the modules within each layer.  This means some changes to my intentions, but I can make that work.  I am still going to maintain the audit functionality in a separate database from the Line of Business database, and I will explain my reasoning's for that when I release a new version of that little project.

Thirdly, I am going to write code that has a designated purpose.  I am going to achieve something that I can use as a vehicle to learn.  It has been said that without vision people perish.  Probably from not having a goal and aimlessly wandering around til they did. I am hoping that with a goal to aim for, I can be more focused on doing and learning rather than wandering down a dark alley.

As an aside, this is the point of me coding and writing blogs about what I am doing and my thoughts on it all.  I am wanting to learn, and I just happen to be in a position where I can ask people to check my blog and code.  If one stops being teachable, stops wanting to learn, then they are, in my opinion, not worth listening to.  I don’t want to be one of those people.  Other than fixing formatting issues and typos, I wont be altering or removing the previous posts.  It is a reminder to me of mistakes I have made to teach me not to make them again.

So, my next post will detail what I am aiming to do with my audit scripts, which I will do try to get out as soon as I can.

Monday, May 10, 2010

Names and Meanings

As you might expect, I am going to use the Autofac IoC container to write a decoupled application the does "stuff". I haven't defined much of what I want this application to do, as I have mentioned in an earlier post, I just want to learn.

One of the things rattling around in my head is how to name the database objects. It seams like something trivial, I mean what's in a name? But names have meaning, and just as with naming children changing them later in life can cause more problems than it is worth!

My options as I see them are to name the objects with names that match the tables or to add a prefix to the table names, still having some semblance to the name of the object. Let me go through my thoughts.

My first option is to name the tables names that reflect the objects they represent. Names like user, settings and individual.  This would help in matching the data store to the entity layer, and any custom queries would be easy to read.

Select * from [user]
inner join individual on [user].id = individual.id

This is easier to read and understand at a glance.  It returns the user and the individual that it is attached to. Simple.  But here is my problem with that.  I am attempting to write a decoupled application.  What if I want to move one of the parts to another set of servers? For example, if the core of the app gets more use than the rest, then performance wise wouldn't I be better moving it if I could? And I don't just mean the presentation layer or the model, but the data layer also? The problem with this naming approach is that I can't tell, from a data layer perspective, which table belongs to which module.

The second option is to attach a prefix to the table names, which could signify what part of the application it was apart. It turns the earlier SQL statement into

Select * from acsUser
inner join coreIndividual on acsUser.id = coreIndividual.id

Which is not as readable, but I can tell the module that each part comes from. Now for a simple example it isn't too bad, but for more complex examples it can get rather difficult to manage.

I guess the question is how decoupled do I want the code to be? I was speaking to a friend and he said that a decoupled application was rarely going to be decoupled at the data layer. How many places can afford to have multiple database servers in production (that are not replicated and the like)?

Also, if I decouple the data layer, that can create it's own issues, like how to search across multiple parts of the app? How to maintain data integrity across multiple sources? And another issue, how do I maintain data access security across those different modules?

After much thought, I have decided to write an extremely decoupled app, one where it is decoupled from the data layer up. There are 2 reasons for this. One is that I am doing this to learn how to improve my coding. And two, I like a challenge. So I am going to write each "module" with it's own database, web service, and then write integrative UX environments that bring it all together! So now I need to review the architecture of the app, to make sure that it is in line with this.

Sunday, May 2, 2010

Autofac 2.2 and Me: My First Look at an IoC

Well, since I had the database audit working to my satisfaction (not to a production multi server high volume level, but working enough), it is now time to start working on my c# code skills.  While I am working to get a system working, I am not specifically wanting to achieve a specific project like I was for the audit, but rather making sure I am playing with various technologies.  Things like C#, WCF, Silverlight, maybe some WPF, and MVC.  Any other things I should be trying just let me know.

So, my first learning is going to be the concept of an IoC container. Here are the simple steps I took to implement it.  Please note I have not any direct experience with IoC containers, and only a weeks worth of reading here and there on Autofac and IoC containers.  This basically means that I have gotten it working, but it isn't necessarily the best implementation, so please, any feedback would be appreciated.

But before I explain how I got it working, let me explain (to my understanding) why you should be using an IoC Container.  One of the hardest things to do is make any major changes to an existing system.  This is because they are usually written with a single objective in mind, to fulfil the requirements.  Now, when you want to change a part of your code, it is simple.  However, if you want to remove an entire section of the code (for example change the database type), this gets harder.  Using interfaces has helped with this, in that you can write to an interface, and when you want to change the implementation you can create another version to the interface, and substitute it with the old version.  But, the down side is that you need to find all the references and update them.  Here is where IoC Containers come into play.

With an IoC container, in one place you can change the implemented class, where the IoC is built, rather than having to find every instantiation of the old class to change it to the new one.  This can lead to a more decoupled application, one that has as many of its parts (code wise) not reliant on the other parts, but on definitions of what the code is meant to do.  As a result, these parts can be interchanged with greater ease.

Now, back to the implementation of the Autofac IoC container.

The Steps to IoC Goodness

  1. Downloaded the source
  2. Added the resources to my projects
  3. Created the Container
  4. Updated my code to use the container
Downloaded the source
The first step was to download the source from the project home.  The homepage of the Autofac project is here, and the download page is here. Please note that there is a .Net 3.5 version and a 4.0 version, so choose the version that best suits you. (Or best suits your code, to be more precise.)

Added the resources to my projects
Next, I added the dll files to my projects.  I added them to my code project and also the test project.  The code project cause that is where object interfaces and the like are registered with the IoC Container, but also in my test project cause that is where the container is tested to make sure that I have gotten the container working properly (the whole point of a test).

Created the Container
Next, in my project, I added the container to my code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autofac;

namespace Nyx.Core.Universal
{
public sealed class AutofacContainer
{
// Added a private constructor to stop the auto creation of a public one
private AutofacContainer()
{
}

public static IContainer BuildContainer()
{
var builder = new ContainerBuilder();

builder.RegisterType<DatabaseSession>().As<IDatabaseSession>();
builder.RegisterType<DataAccessTest>();

var container = builder.Build();
return container;
}

}
}

Please note that the basis of this is to prove a test, to make sure that the code is functioning properly.  The constructor for the DataAccessTest object has a dependency on IDatabaseSession (see the DataAccessTest code below). Now, note that the 2 register statements are different.  This is because I am in the first case, telling Autofac that when it sees the interface IDatabaseSession it should use the concrete class DatabaseSession.  This is not actually required, as but am just learning so I explicitly code it that way.  If you see the second register line, you will see that it is just registering the class, no interface reference.  This is how I could have written the first line, the interface being inferred.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nyx.Core.Entities;
using Nyx.Core.Universal;
using NHibernate.Linq;

namespace Nyx.Core
{
public class DataAccessTest
{
IDatabaseSession _sessionLocator;

public DataAccessTest(IDatabaseSession sl)
{
_sessionLocator = sl;
}

public User GetUser()
{
User result = null;

using (var session = _sessionLocator.OpenSession())
{
var query = from ticketingOffer in session.Linq<User>()
where ticketingOffer.UserId.Equals(1)
select ticketingOffer;
result = query.FirstOrDefault();
}
return result;
}
}
}

The database session is just a connection that through fluent nHibernate connects to a MS SQL 2008 Express edition database, and I wont bore you with that code.

4. Updated my code to use the container


So, I have updated the code by adding the IoC container to the core, and creating a test class to prove my point, I have written a unit test to show that it is all working.

[TestMethod]
public void Autofac_database_integration_test_should_return_valid_user()
{
using (var container = AutofacContainer.BuildContainer())
{
var TestObject = container.Resolve<DataAccessTest>();
var result = TestObject.GetUser();

Assert.AreEqual(1, result.UserId);
Assert.AreEqual("lkoutzas", result.UserName);
}
}

Now, this code creates the Autofac IoC, and then it resolves the DataAccessTest class, automatically resolving the DatabaseSession class.


And there you have it.  I haven't added everything that I have done, just the highlights to get Autofac working.  Again, this is my getting it working, not the implementation of a pattern or anything.


Happy Containing!