# Tuesday, February 19, 2008

I'm just finishing up building my first deployed WCF service, and over the past couple of months I've learned a lot about WCF - what works and what doesn't from a practical standpoint.  Unfortunately there are still a few areas in which I'm fuzzy.

I was originally treating my WCF proxies like ASP.NET 2.0 web service proxies.  Create a proxy and then let the GC handle it.  This was really useful because I was just injecting the service instance into each of my MonoRail controllers using Windsor.  Testing was nice and easy, and things looked good.

Until last week... I discovered a nasty bug in my web application.  The bug was, that under load, the WCF service would stop responding and timeout.  Come to find out that it's not only recommended to close your client side proxies, but required (at least when using Net TCP binding).

This turned my beautiful code with its inverted dependencies into a mess.  I had to start asking the container on every call for a new proxy since it was getting closed after every remote call.

IMyService svc = IoC.Resolve<IMyService>();
svc.SomeRemoteCall();
svc.close();

 

I had to do it this way because the remote calls were wrapped in a local service helper object that didn't have any idea about the unit of work, i.e. where the best place to put the Close() call.

 

When I have some time this week I plan on building a WCF proxy helper that will create a proxy unit of work on a per HTTP request basis.  When the HTTP request comes in, the proxy is created, and when the HTTP request finishes the helper will call Close() on the proxy.  This should allow me to remove the ugly static IoC dependency and use Windsor to inject the proxy instance.

Tuesday, February 19, 2008 6:59:24 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, February 12, 2008

After some research I discovered the MyMeta API used by MyGeneration for DB meta data is now open source under the very liberal BSD license!  That sure makes my life a lot easier since it has a much more fully featured API than I started to build.  Even better it supports multiple RDMS out of the box: SqlLite, MySql, SQL Server, Access, Oracle etc.

This means that I can programmatically walk a database definition using C# in a generic way.  The API is somewhat similar to SMO, but primarily uses OLEDB to pull: DB, table, column, view, index, and sproc definitions from the different providers.

What surprised me is that the MyMeta API has interface definitions for everything; interface definitions that have the same names and properties as the interface definitions I had already created in SQLMigration.  I only had to change the namespace using statements in a few places and add a reference to MyMeta.dll to start using it with my existing code.

I haven't fully tested this out, but assuming MyMeta works as advertised, it should cut back development time significantly.

Tuesday, February 12, 2008 8:24:19 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, February 10, 2008

I finally got one of the harder unit tests for my SqlMigration tool passing.  The interesting thing is that I'm using NHibernate to populate my object graph of objects that describe the database.  I'm just using standard SQL queries that hit the INFORAMTION_SCHEMA tables.  Here's one of the tests:

[Test]
public void ShouldReturnAddressForeignKeys()
{
    ITable address = session.Get<Table>("Address");
    ITable state = session.Get<Table>("StateProvince");
 
    Assert.IsNotNull(address, "No address table returned");
    Assert.IsNotNull(state, "No state table returned");
    Assert.IsNotNull(address.Columns, "No address columns returned");
 
    Assert.AreEqual("FK_Address_StateProvince_StateProvinceID",
        address.Columns[4].ForeignKey.Name, "Incorrect FK name");
 
    Assert.AreEqual(address.Columns[4],
        address.Columns[4].ForeignKey.ForeignKeyColumn, "ForeignKeyColumn StateProvinceID is incorrect");
 
    Assert.AreEqual(state.Columns[0],
        address.Columns[4].ForeignKey.PrimaryKeyColumn, "PrimaryKeyColumn StateProvinceID is incorrect");
}

Unfortunately I just realized that you can have a compound primary key so I really ought to change ForeignKey.PrimaryKeyColumn to a list ForeignKey.PrimaryKeyColumn[0]...

Using NHibernate for this kind of work probably isn't the easiest solution, but once the mappings are right NHibernate takes care of correctly populating the object graph which isn't trivial because of all the bidirectional associations.  I've definitely learned a lot about NHibernate mappings and SQL Server's INFORMATION_SCHEMA views. NHibernate really is flexible and powerful and NHibernate makes loading a specific object from the database very easy and fluent.  The only "code" I had to write were the XML mapping files besides building a SessionFactory. 

It does seem that using NHibernate to directly query SQL Server is too time consuming development wise especially when other people have already figure this stuff out. If there were am easy way to generate NHibernate mapping files at runtime for a DB I could probably use NHibernate's rich meta data model instead of, or in addition too.  Another possibility is to use MyGeneration's data model or even SMO to populate my entities.

In some ways it seems like I'm reinventing SMO, but at least I have the source code to my version of SMO and my version doesn't have a hard dependency on SQL Server ;-) even if SMO has a lot more functionality.

Sunday, February 10, 2008 5:32:22 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, February 09, 2008

I thought this looked like an interesting approach to validating your SQL statements in a continuous integration environment.  Basically you execute the script with the NOEXEC option.

I'm not sure I would actually us it though since I think I would prefer to actually run the scripts and and then do some further processing, however maybe this is a good prebuild step?

Saturday, February 09, 2008 5:39:37 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  | 
# Sunday, February 03, 2008

I'm working on creating a SQL migration tool to help automate some of the drudgery in moving and upgrading databases.  Initially I'm only supporting SQL Server 2000 since this is what I primarily use.

The SQL scripts are being generated from the SQL entities (sort of like a generic SMO) via NVelocity templates.  I think the NVelocity approach is working very well because the C# code only needs to populate the top most object, like Table or Column, and the template can walk the hierarchy db objects as needed.

Right now I have Create/Drop table, Add/Drop/Alter column, Create/Drop index, Create/Drop foreign key complete.  This should be enough to modify a table for the most common scenarios.  Currently the committed code only has SQL script generation via the scripting API, so there's no intelligence currently backing it in regards to migration.  It only will write SQL scripts at this point.

The one thing I'm making sure to do, is to bulletproof the generated scripts so they can safely be run multiple times without error.  Here's an example template which safely adds a column to a table.

/****** Object:  Column [$column.Table.Schema].[$column.Table.Name].[$column.Name] $time ******/

IF NOT EXISTS
(
  SELECT * FROM [information_schema].[columns]
  WHERE table_name = '$column.Table.Name'
  AND table_schema = '$column.Table.Schema'
  AND column_name = '$column.Name'
)
BEGIN
  ALTER TABLE [$column.Table.Schema].[$column.Table.Name]
  ADD $SqlScriptHelper.WriteColumn($column)
END
GO

 

I chose to use NVelocity templates because of their flexibility and the ease of use for generating text documents.  NVelocity is also faster for script generation then SMO (and it actually works unlike SMO), and it gives me the flexibility to do things the non-SQL Server way which sometimes is inappropriate for production systems (change a column's nullability and you'll see what I mean).  One more benefit, is it allows me to customize the output just by modifying the template, no recompile necessary.

Keeping my SQL generation separate from SQL Server will also allow me to re-use this migration tool for other databases like MySql.  It could even potentially allow me to export scripts from SQL Server to MySql syntax since I have an abstraction layer over the database like an ORM would.

Sunday, February 03, 2008 8:10:27 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, February 02, 2008

What would the minimum set of features be to create a SQL Schema Migration tool?

Add FK Contraints
Remove FK Contraints

Add Non-Clustered Indexes
Remove Non-Clustered Indexes

Add Tables
Remove Tables

Add Columns
Remove Columns

Add Sprocs
Remove Sprocs
Alter Sprocs

Add Views
Remove Views
Alter Views

LHS is a dependency of the RHS

Add dependency order (removal dependency order is the opposite):
Tables -> Columns -> FKs -> Views -> Sprocs

Are there other common scenarios I'm not think about?  Like changing the nullability of a column or adding/removing a default?

Saturday, February 02, 2008 11:03:23 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, January 23, 2008

Over the past few months on the RhinoMocks group I have seen several good ideas for enhancements to the library.  One of the ideas was to add a DoNotExpect.Call helper, which would do the same thing as the LastCall.Repeat.Never() syntax, just in a much more concise way.

This past weekend I added the DoNotExpect.Call() syntax to RhinoMocks, and Ayende has already applied the patch to the RhinoMocks trunk.  Here's how you use the new syntax:

IService svc = mocks.DynamicMock<IService>();

DoNotExpect.Call(svc.Load("Sneal"));

DoNotExpect.Call(delegate { svc.Save("Sneal"); });

 

There are two overloads for the method, one takes an object, and the other a delegate.  For methods that return a value you can use the simpler one without the delegate, however for void methods you need to use the delegate syntax (since something has to be passed in, even if it is technically ignored).

I'm excited about the syntax since I know I will use it quite often on my controller tests that use a lot of dynamically mocked objects.  The syntax I think is also easier to understand, especially for RhinoMocks newbies who have used NMock2 before.

Hopefully I'll have time to add some other enhancements to RhinoMocks in the near future.  It feels good to give back to the software ecosystem every once in a while.

Wednesday, January 23, 2008 6:16:24 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 

I just added another tool to my PC tool belt today thanks to Jeff Atwood.  This got me thinking about all the tools I use for development and just general day to day use of my PC.  Here's a list of one's that I use pretty often.

Development specific tools:

  • Consolas Font Family for Visual Studio 2005/2008 - Makes a nice legible Visual Studio font
  • Fiddler2 - Good for debugging anything over HTTP
  • GhostDoc2 - Quick start my class and method documentation - intelligently.
  • HM NIS Edit - IDE for NSIS installers.
  • IE Developer ToolBar - Firebug light...
  • ReSharper 4 - VS Refactoring tool.
  • MBUnit - xUnit tools for .NET
  • NUnit - xUnit tools for .NET
  • Firebug - Firefox plugin for debugging JavaScript, CSS, and HTML.  Absolutely essential for any web dev.
  • YSlow - Yahoo's web performance analysis tool.
  • WatiN - I use this to drive tests through IE.  Its pretty easy to setup and use.  The newest version supports FireFox!
  • Notepad++ - Opens as fast as Notepad, but has tabs and syntax highlighting.  It comes with a nice installer which adds it to the IE view source context menu.
  • SharpDevelop - Used for editing Boo/Brail.  I think I also used this when I was developing Mono applications on Ubuntu.
  • Subversion - This is what I use for source control at work and at home.
  • Tortoise SVN - Explorer plugin for Subversion.
  • Visual SVN - Non-intrusive Visual Studio plugin for Subversion that just works.
  • Visual Studio 2005 - My C#/C++ IDE.
  • Visual Studio 2005 SP1 - You gotta have web projects.
  • Visual Studio 2005 Extensions for .NET 3 - Use this mainly for WCF.
  • CSAH - Allows you to cut and paste as HTML from Visual Studio.  Essential for blog posts.
  • Syntax Highlighter for WLW - This one works well with every programming language I use.
  • SQL Server 2005 Dev Edition - Primarily the DB I use.
  • SQL Server CE - Sometimes use this for unit tests with NHibernate.
  • MySQL - Started using this recently, the installer for Windows makes it dumb easy to setup.
  • Java SDK 1.6 - uh yeah.
  • Eclipse - Sometimes need this for Java (and C++ programming on Linux).
  • ActivePerl - Our C++ xUnit test framework requires this.  There's a free version if you click the right link.
  • CxxTest -C++ xUnit test framework.
  • RhinoMocks - Fluent mock object framework for .NET.
  • PowerShell - A powerful Windows command shell.
  • CruiseControl.NET (CCTray) - Keep the team in touch with the build.
  • WinMerge - Nice merge/diff tool especially considering that its free like beer.
  • TestDriven.NET - Since I'm now force to use MSTest, this an essential tool to keep the TDD rythm.
  • FxCop - Nice to run every once in a while... to catch stuff, especially related to globalization.

Non-Development specific tools:

  • Virtual PC 2007 - Use this run virtual PCs, generally for integration testing.
  • Miranda IM - I get tired of having multiple IM clients, this allows me to use them all at once (and it's OSS).
  • Pidgin - Multi-function IM client which just works.  Much better than Miranda.
  • Firefox3 - My preferred browser, which runs JavaScript heavy sites fast.
  • 7-Zip - An awesome zip/tar/rar/whatever utility.
  • FoxIt PDF Reader - A light and fast version of Adobe Reader that doesn't constantly nag me about updates.
  • ClipX - My newest install, this one allows you to maintain a clipboard history.  I'm loving this one.
  • DisplayFusion - I generally just use this to drag maximized windows between monitors.
  • Windows Live Writer - What I write this blog on.
  • Paint.NET - A powerful .NET paint and photo editor package.  I've dumped my old copy of Photoshop 7 for this.
  • Launchy - Since I'm stuck on XP, this makes finding and starting programs uber quick.

The one overriding theme of all these packages is that most of them are free and/or OSS.  Pretty cool.

Wednesday, January 23, 2008 2:17:41 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, January 22, 2008

While looking for information on multi-threaded debugging for Visual Studio 2005, I found this article by Peter Bromberg that has some decent Visual Studio 2005 debugger tips.  Its definitely worth reading over if you use Visual Studio 2005.  I know I learned a thing or two.

One tip I would add to this article is to use the immediate window when debugging.  It seems like all VB'ers know about this one, but relatively few C# developers do. 

The immediate window allows you to evaluate code while debugging.  Lets say I wanted to print out the value of a property in the immediate window, I could do any these expressions:

ImmediateWindow

I find this is often faster than trying to dig through a watch window, especially on a large class.

You can even call code directly from the immediate window, which I think is where it's real power lies.  With this you can create a generic debug method in your code that prints out all the values of a collection, which can then be called from the immediate window passing in any collection.

internal static void PrintAll(IEnumerable coll)
{
    foreach (object item in coll)
        Debug.Print(item.ToString());
}
Tuesday, January 22, 2008 5:17:53 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |