Tuesday, September 02, 2008

Umbrella- collections++

As soon as the .NET framework allowed room for extension methods, this kind of thing was bound to happen. Umbrella is a 3rd party open source lib that adds extension methods and intuitive helper classes that make you wonder why they weren't there in the first place. The official codeplex site is here and the author's site is here. There are quite a few useful bits in this library for multiple purposes, but the real beauty comes through in its collections enhancements.

 

The downside of umbrella is its immaturity. To this date of september '08 I couldnt find any "official" documentation of the library per se (outside of blogs such as mine or Ayende's). Then again, maybe the unit tests speak for themselves. I sense that this project is a moving target, meaning that it is one of those open source projects in state of flux, which can make it a little hard to document.



Foreach on an IEnumerable

IEnumerable<string> items = new List<string> {"1", "2", "3", "4", "5"};
IList<string> actionItems = new List<string>();
//the old way
foreach (string s in items)
{
actionItems.Add(s);
}
//the umbrella way
items.ForEach(actionItems.Add);


Indexed foreach actions:

IEnumerable<string> items = new List<string> {"1", "2", "3", "4", "5"};
string[] actionItems = new string[5];
//the old way
int i = 0;
foreach (string item in items)
{
actionItems[i++] = item;
}
//the umbrella equivalent
items.ForEach((i, item) => actionItems[i] = item);


Pairing two lists of equal length together


IEnumerable<string> items = new List<string> {"1", "2", "3", "4", "5"};
IEnumerable<string> otherItems = new List<string> { "6", "7", "8", "9", "10" };
IEnumerable<Pair<string>> pairedItems = items.Pair(otherItems);
Assert.Equal(5, pairedItems.Count());
Assert.Equal("1", pairedItems.First().X);
Assert.Equal("6", pairedItems.First().Y);


Lazy-loading lists:

//lists that are declared but not consturcted until access-time
var list = new LazyList<int>(() => new List<int> { 1, 2, 3 });


Read-only lists:

//lists that cannot be added/removed from (without resorting to DataViews)
//ReadOnlyCollection is a part of the core .NET library, it takes an IList<T> as a constructor //argument
ReadOnlyCollection<string> readonly = list.AsReadOnly();


Lists that convert between types
(This one is intricate and I am still studying it)

//Funcs is actually a generic collection of strategies for converting between types.
//the real magic behind conversion comes from
//System.ComponentModel.TypeDescriptor.GetConverter(type).ConvertFrom(value)
IList<string> adapter = new ListAdapter<int, string>(
new List<int> { 1, 3, 4 },
Funcs<string,int>.Convert,
Funcs<int,string>.Convert);

Assert.Equal(1, adapter.IndexOf("3"));

These are the pieces that I am using within my projects, but I am only scratching the surface. I suppose when it somes to collections, you can't have too much extensibility.

Download it, use it, or simply wait until these features are folded into the .NET lib in the next release ;)

Labels:

Tuesday, August 19, 2008

Sharepoint C# HTML Trick: Is this fluent programming or sleazy hack?

The challenge: writing custom sharepoint web-parts can be painful because there is no inline code markup. (and I'm NOT using the "smart part" )

How to write HTML using nothing but C#?
HTML is a tree just like any other AST.

This is the code I wanted to write:


<asp:Table Width="100%">
<asp:TableRow>
<asp:TableCell Width="100%" CssClass="headerRow">Alphabetical Search</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell Width="100%">
<asp:GridView runat="server" Width="100%" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>



This is the code equivalent (plus databinding) using fluent constructors using C#:


protected override void CreateChildControls()

{

var dataFeed = new List

{

"one",

"two",

"three"

};

var gridView = new GridView

{

Width = new Unit("100%"),

DataSource = dataFeed,

Visible = true

};

gridView.DataBind();

var table = new Table

{

Width = new Unit("100%"),

Rows =

{

new TableRow

{

Cells =

{

new TableCell

{

Text = "Alphabetical Search",

CssClass = "headerRow"

}

}

},

new TableRow

{

Cells =

{

new TableCell

{

Controls =

{

gridView

}

}

}

}

}

};

Controls.Add(table);

base.CreateChildControls();

}




Nothing earth shattering here, but I actually dont mind using this syntax. This is the result:






**EDIT** this style of programming runs out of gas rather quickly when you are faced with the need for better interaction. A better solution is to use the "smart template" project templates at codeplex:

Labels: , ,

Thursday, January 31, 2008

Basic Property Coding Conventions in C# 3

This is a question that is arguably aesthetic: the following two classes are functionally equivalent. Which way would you prefer to write your classes?
    public class Foo
{
public string Name
{
get;
private set;
}
public Foo(string name)
{
Name = name;
}
}
or
    public class Foo
{
private string m_Name;
public string Name
{
get { return m_Name; }
}
public Foo(string name)
{
m_Name = name;
}
}
Does one stand out to you as the better way?

Labels:

Wednesday, January 23, 2008

Model-View-Controller Architecture for WPF: An Approach.

Do you know that disappointing feeling you get, when you learn a new technology, you start using it, just to discover that all the examples of the new technology across the internet don't amount to a practical real-life application?

The problem with conventional WPF examples
I am far from an expert in UI, especially windows forms UI, which makes me the perfect victim for bad examples. This is the feeling that I am getting with WPF right now. Where are the best practices? Its a very impressive technology, and it makes for some very entertaining parlor tricks. We see new sample interfaces that look like video games. We see a plethora of code samples for new tricks, but few of them form to any semblance of a practical windows application.

New Technology Causes new Confusion

The other thing we get with WPF is a very dangerous period of conceptual oblivion as we try to figure out where we should define the bindings, where should we define behavior, where to draw the line between presentation and logic etc.
  • Should I use a ContentTemplate? Maybe a DataTemplate?
  • Should I define my bindings declaratively, or should I do it manually in the codebehind? If I do it in the XAML, should I use the XAML notation, or the odd new binding syntax with the curly braces?
The questions go on and on... OK I have X-teen ways to do the same thing, which way do I go?

One thing I am discovering (the hard way) is that if you just want to write a normal program, a lot of the classic design patterns are still very relevant with WPF.

The Danger of "Direct" DataBinding
DataBinding is where I got burnt.
Think about it: everywhere you look, you see examples of a WPF UI directly bound to a business object. Direct binding between the UI and a business object has some dangerous implications:
  • As I type/click etc... I am causing immediate changes to the business object. How do I undo them?
  • Since the binding is two-way and immediate, does this mean I no longer need an "Apply" button anymore?
  • What if I want to cancel what I was just doing?
I was writing a program where the UI was directly bound to my business objects. I had a textbox bound to the "Name" property of an object. My object throws an exception if its passed a name that is empty, or too big.

What happens when I type beyond this limit? As a default behavior, WPF swallows the exception! It turns out you need to write a custom binding object to display the exception to the user in a messagebox.

What is the recommended solution for databinding to objects? Your objects need to implement IDataErrorInfo. The gist of implementing IDataErrorInfo is this:

public virtual string this[string propertyName] {
get {
//find the property that matches the string "propertyName"
//check the current state of the property, is it valid?
//if its valid, return string.Empty
//if its invalid, return a formatted error
}

This code gives me a migraine headache. Why should my business objects EVER exist in an invalid state?
The recommended solution seems like an antipattern to me. Imagine that, all of your business objects implementing INotifyPropertyChanged, INotiftyCollectionChanged, IDataErrorInfo just so they can work with WPF?

But still, databinding is a very cool feature in WPF. How to leverage this without violating my model? I made a mistake, I was so focused on using new WPF tricks that I forgot how to build a good testable application.

My (current) Solution

MVC is a design pattern intended to solve the problem between separating a UI and the logic. These were the qualities I was looking to achieve:
  • "smart" business objects, they throw exceptions if you try to pass them anything invalid, or something goes wrong in an operation
  • "dumb" WPF UI that is bound in a dynamic, readonly fashion to the objects
  • The UI catches exceptions and shows them to the user in a messagebox
  • A "controller" that receives gestures from the UI and performs logic on the model
  • The controller should be very testable
  • The UI should be very mockable
  • The UI has no direct write access to anything in the business objects
The Sample Program: the cliche Blogger Application ala WPF

The sample program is here. It is a very simple, practical windows program for adding/editing/removing blog posts. The main attraction is the architecture.

The Models
The model is simple. I have a Blog that contains a collection of BlogEntries, and they are both "Persistable" meaning they have an ID and a name.
The Blog class exposes a list of its BlogEntries, but it has specialized Add/Remove methods for modifying this list.









The Views


Since I needed the view to be mockable, I set up for an interface, such as IView.
Any view must have an associated controller, and be able to update its display with the latest data. I create a view for every aspect of the program. In this case, I have a view for BlogEntries, and a view for Blogs. These views generate events that are handled by the controllers. They use BlogEntryEventArgs as arguments for the events.




The Controllers

The controllers exist to handle generated events from the views, and this is where the real business logic begins. As you can see, there is an event handler for every event in the view. One noteworthy thing here is that the controller does not need to talk back to the view for updates because the view is directly bound (in a readonly fashion) to the model. That little feature is thanks to the WPF databinding power!







Finally, The UI

The UI is two windows, one for selecting blog entries and one for editing them. Each window implements a view. Upon window construction, each window registers a controller. Button callbacks from the UI generate events sent to the controller. The windows catch and display any exceptions, and the UI is automatically updated by the direct databinding to the model.

What about tests?

How to test UI interaction without a UI? Make a "mock" of the views, and test the controller. Since our views are dumb, we can effectively test the bulk of the application using a dummy view. For example:


private class MockBlogEntryView:IBlogEntryView{...}

///
/// isolate the controller for testing
///

[Test]
public void TestCreate()
{
Blog _blog = new DummyBlogDAO().GetByID(0);
MockBlogEntryView _mockBlogEntryView = new MockBlogEntryView();
BlogEntryController _blogEntryController = new BlogEntryController(_mockBlogEntryView);
BlogEntryEventArgs _blogEntryEventArgs = new BlogEntryEventArgs(null, "blahblahblah", "New post", _blog);
_mockBlogEntryView.ThrowCreateEvent(_blogEntryEventArgs);
}
At this point, feel free to replace MockBlogEntryView with something from your favorite mocking API such as Rhino Mocks or TypeMock.NET if you are too lazy to define a dummy view.

Other Observations

Admittedly, this is yet but another simple example for a tricky concept. Does this architecture scale nicely as the complexity grows? Your mileage may indeed vary.
In my example, I have a view-per-model design, but
  • There is no real correlation at all between the number of views you have and the number of "model" objects.
  • There is no real correlation between the number of controllers you have and the number of views either. (In retrospect, perhaps I only needed one controller)
There is never a single and straight path of correctness for building any complex app; there are many right ways. I'll post again when I see how this architecture holds up to the test of time and complexity.

Download the Source Code here

Labels: ,

Wednesday, December 19, 2007

Generic Custom NHibernate Collections - A Second Swing

I talked about custom collections for WPF and NHibernate back here, but I wanted to mention that I made an alternative solution that has less lines of code and it is apparently easier for other people to understand.

A quick recap: We want to harness the powerful databinding features of WPF. To optimize the two-way binding functionality, our objects need to implement INotifyPropertyChanged. No problem there, but our collections need to implement INotifyCollectionChanged, which is problematic, because our collections are commonly IList(T)s.

Why does NHibernate use an IList? When declaring a transient (new) object, we always write something such as the following:

private IList InnerType m_InnerItems = new List<InnerType>();

A "transient" collection is a new or unsaved collection that was created in your code, and the concrete implementation of "IList(T)" is a "List(T)". A persistent (saved) object is not built by your code, it is built by NHibernate. It is still an "IList(T)", but the concrete implementation is a PersistentGenericBag(T).

The PersistentGenericBag class has no default constructor, it requires an ISession as a construction parameter to support the "Lazy-Loading" magic. Since PersistentGenericBag has no default constructor, it wasn't designed for us to use in transient collections. Besides, why would we want to use an NHibernate-implementation-specific type inside of our domain objects? That would couple our domain objects too tightly with NHibernate specific implementation, in my opinion.

What to do? We need to make a new interface (I defined mine to implement INotifyCollectionChanged for my uses, but this could implement anything you need for your purposes):

using System.Collections.Generic;
using System.Collections.Specialized;

namespace NotifyingCollectionDemo.Library.Collections
{
public interface IDomainCollection<T>:INotifyCollectionChanged, IList<T>
{
}
}

We need to define a new "Transient" collection type for our interface:

using System.Collections.Generic;
using System.Collections.Specialized;

namespace NotifyingCollectionDemo.Library.Collections
{
public class TransientDomainCollection<T>:List<T>, IDomainCollection<T>
{
#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
/// <summary>
/// Fires the <see cref="CollectionChanged"/> event to indicate an item has been
/// added to the end of the collection.
/// </summary>
/// <param name="item">Item added to the collection.</param>
protected void OnItemAdded(T item)
{
if (this.CollectionChanged != null)
{
this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, item, this.Count - 1));
}
}
/// <summary>
/// Fires the <see cref="CollectionChanged"/> event to indicate the collection
/// has been reset. This is used when the collection has been cleared or
/// entirely replaced.
/// </summary>
protected void OnCollectionReset()
{
if (this.CollectionChanged != null)
{
this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Reset));
}
}
/// <summary>
/// Fires the <see cref="CollectionChanged"/> event to indicate an item has
/// been inserted into the collection at the specified index.
/// </summary>
/// <param name="index">Index the item has been inserted at.</param>
/// <param name="item">Item inserted into the collection.</param>
protected void OnItemInserted(int index, T item)
{
if (this.CollectionChanged != null)
{
this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, item, index));
}
}
/// <summary>
/// Fires the <see cref="CollectionChanged"/> event to indicate an item has
/// been removed from the collection at the specified index.
/// </summary>
/// <param name="item">Item removed from the collection.</param>
/// <param name="index">Index the item has been removed from.</param>
protected void OnItemRemoved(T item, int index)
{
if (this.CollectionChanged != null)
{
this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Remove, item, index));
}
}
#endregion

/// <summary>
/// we need to re-implement the IList methods to support observability
/// </summary>
/// <param name="item"></param>
#region IList<T> members
public new void Add(T item)
{
base.Add(item);
this.OnItemAdded(item);
}
public new void Clear()
{
base.Clear();
this.OnCollectionReset();
}
public new void Insert(int index, T item)
{
base.Insert(index, item);
this.OnItemInserted(index, item);
}
public new bool Remove(T item)
{
int index = this.IndexOf(item);
bool result = base.Remove(item);
this.OnItemRemoved(item, index);
return result;
}
public new void RemoveAt(int index)
{
T item = this[index];
base.RemoveAt(index);
this.OnItemRemoved(item, index);
}
#endregion
}
}

We need to define a new "Persistent" collection type for our interface:

using System.Collections.Generic;
using System.Collections.Specialized;
using NHibernate.Collection.Generic;
using NHibernate.Engine;

namespace NotifyingCollectionDemo.Library.Collections
{
public class PersistentDomainCollection<T>:PersistentGenericBag<T>, IDomainCollection<T>
{
#region constructors
public PersistentDomainCollection(ISessionImplementor session, IList<T> coll) : base(session, coll)
{
}
public PersistentDomainCollection(ISessionImplementor session) : base(session)
{
}
#endregion

#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
/// <summary>
/// Fires the <see cref="CollectionChanged"/> event to indicate an item has been
/// added to the end of the collection.
/// </summary>
/// <param name="item">Item added to the collection.</param>
protected void OnItemAdded(T item)
{
if (this.CollectionChanged != null)
{
this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, item, this.Count - 1));
}
}
/// <summary>
/// Fires the <see cref="CollectionChanged"/> event to indicate the collection
/// has been reset. This is used when the collection has been cleared or
/// entirely replaced.
/// </summary>
protected void OnCollectionReset()
{
if (this.CollectionChanged != null)
{
this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Reset));
}
}
/// <summary>
/// Fires the <see cref="CollectionChanged"/> event to indicate an item has
/// been inserted into the collection at the specified index.
/// </summary>
/// <param name="index">Index the item has been inserted at.</param>
/// <param name="item">Item inserted into the collection.</param>
protected void OnItemInserted(int index, T item)
{
if (this.CollectionChanged != null)
{
this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, item, index));
}
}
/// <summary>
/// Fires the <see cref="CollectionChanged"/> event to indicate an item has
/// been removed from the collection at the specified index.
/// </summary>
/// <param name="item">Item removed from the collection.</param>
/// <param name="index">Index the item has been removed from.</param>
protected void OnItemRemoved(T item, int index)
{
if (this.CollectionChanged != null)
{
this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Remove, item, index));
}
}
#endregion

/// <summary>
/// we need to re-implement the IList methods to support observability
/// </summary>
/// <param name="item"></param>
#region IList<T> members
public new void Add(T item)
{
base.Add(item);
this.OnItemAdded(item);
}
public new void Clear()
{
base.Clear();
this.OnCollectionReset();
}
public new void Insert(int index, T item)
{
base.Insert(index, item);
this.OnItemInserted(index, item);
}
public new bool Remove(T item)
{
int index = this.IndexOf(item);
bool result = base.Remove(item);
this.OnItemRemoved(item, index);
return result;
}
public new void RemoveAt(int index)
{
T item = this[index];
base.RemoveAt(index);
this.OnItemRemoved(item, index);
}
#endregion
}
}

Finally, we need an implementation of IUserCollectionType to tie this all together and use it in the mapping files. Notice how I treat this as a factory class:

using System.Collections;
using System.Collections.Generic;
using NHibernate.Collection;
using NHibernate.Engine;
using NHibernate.Persister.Collection;
using NHibernate.UserTypes;

namespace NotifyingCollectionDemo.Library.Collections
{
public class DomainCollectionFactory<T> :IUserCollectionType
{
#region IUserCollectionType Members
public IPersistentCollection Instantiate(ISessionImplementor session, ICollectionPersister persister)
{
return new PersistentDomainCollection<T>(session);
}
public IPersistentCollection Wrap(ISessionImplementor session, object collection)
{
return new PersistentDomainCollection<T>(session,collection as IList<T>);
}
public object Instantiate()
{
return new TransientDomainCollection<T>();
}
public IEnumerable GetElements(object collection)
{
return (IEnumerable) collection;
}
public bool Contains(object collection, object entity)
{
return ((IList) collection).Contains(entity);
}
public object IndexOf(object collection, object entity)
{
return ((IList) collection).IndexOf(entity);
}
public object ReplaceElements(object original, object target, ICollectionPersister persister,
object owner, IDictionary copyCache, ISessionImplementor session)
{
IList result = (IList) target;
result.Clear();
foreach (object o in ((IEnumerable) original))
{
result.Add(o);
}
return result;
}
#endregion
}
}

How to use this? In your mapping file, something such as:

<bag name="Items" inverse="true" cascade="all-delete-orphan" generic="true" lazy="true"
collection-type=
"NotifyingCollectionDemo.Library.Collections.DomainCollectionFactory`1[[NotifyingCollectionDemo.Library.DomainModel.ListItem, NotifyingCollectionDemo.Library]], NotifyingCollectionDemo.Library">
<key column="ListContainerID" />
<one-to-many class="ListItem" />
</bag>

In the code:

private IDomainCollection<ListItem> _items = new TransientDomainCollection<ListItem>();

public IDomainCollection<ListItem> Items
{
get { return this._items; }
set { this._items = value; }
}

And you should be in business.
I like this code, because the NHibernate-specific stuff is only accessible from the NHibernate-specific factory. The user code never references a PersistentDomainCollection, which makes for a clean cut. Again thanks to Billy McCafferty and Damon Carr, since my solutions are "cannibalizations" of their more original works. Any thoughts?

Labels: ,

Friday, December 07, 2007

C# Perversion: Generic Constructors using Reflection

This MIGHT be useful in the future, but right now I was getting my hands dirty with some reflection code and it intrigued me: generic constructors.
        public AnyType DefaultConstructor<AnyType>()
{
return ExtensibleConstructor<AnyType>(new Type[] {}, new object[] {});
}
public AnyType ExtensibleConstructor<AnyType>(Type[] argTypes, object[] args)
{
Debug.Assert(argTypes.Length == args.Length, "Constructor argument lengths must match");
Type theType = typeof (AnyType);
ConstructorInfo theConstructor =
theType.GetConstructor(argTypes);
Debug.Assert(theConstructor != null,
"This type of class [" + theType + "] doesnt have a matching constructor signature");
return (AnyType) theConstructor.Invoke(args);
}

This code will indirectly invoke any publicly exposed constructor of AnyClass

public void Test()
{
StringBuilder _stringBuilder = DefaultConstructor<StringBuilder>();
_stringBuilder = ExtensibleConstructor<StringBuilder>(new Type[] {typeof (string)}, new object[] {""});
}
I understand the reflection concept, but I am one of those guys that uses it as a last resort, not because of the performance risk, but because I fear it can obfuscate the code.

Labels:

Thursday, December 06, 2007

Unit testing Persistent objects in ORMs such as NHibernate

Even though I am writing this with NHibernate-specific examples, these concepts apply to any ORM technology, so use your imagination a little on this one.

So you're using persistent classes, and you need to make unit tests. Here is a fundamental concern to test with any persistent class:

I want to create an object, then "persist" it. I want to test that the object loaded from persistence matches the object I originally created. Then I have tested the correctness of the mappings.

How do you test to make sure that two objects match each other? I see two concerns:
  1. The immediate values inside of the object are matching (primitive properties, for example)
  2. The "neighbors" that my class has references to also match (many-to-one or one-to-many associated classes).
Consider this scenario: You have a target class X, and you want to test its persistence. Imagine that X inherits from an abstract class such as PersistentObject:
    public abstract class PersistentObject<T>
{
#region members
private int id = 0;
#endregion

#region properties
public int Id
{
get { return id; }
}
public bool IsSaved
{
get { return id != 0; }
}
#endregion

#region methods
public abstract bool Matches(T t);
#endregion
}
This is a very simplistic example, but in this case every PersistentObject has an integer identity primary key. Anything that inherits from PersistentObject must also implement a "Matches" method, which compares objects of a common type to see if the properties match.
I could have overridden the object.Equals method here, but I feel this would obfuscate the meaning of "Equals", so I made a new method.

This "Matches" method is the perfect hook to test the equality of immediate properties (persistent object testing concern #1).

Just because the immediate properties of an object match, does this mean that the objects are the same? No, we must make sure that the "neighboring" objects also match.

For concern #2, we could use a recursive approach, call the "Matches" method recursively on all of the parents and all of the children? I argue this is overkill.

If the target object's parents' IDs are matching, and the target object's childrens' IDs collections are matching, then we have effectively proven that the objects match.

If you have a test for every type of persistent object, then there is no need to call a "Matches" method recursively, because you will be testing the same thing many times over, and the code will be unnecessarily complex.

One important quality of NHibernate to remember: NHibernate guaranteess the reference equality between two objects representing the same row under the same session. This is a very simple, but powerful quality.

Here is the approach I've adopted for unit testing persistence:
  1. Create your database schema from the mappings using the schema export tool.
  2. Use a factory to create some bulk data. If you can, create a rich graph of all of your persistent objects in a realistic scenario.
  3. Using a new session, persist this object graph to the database.
  4. For each type of persistent object,
  • try to load a new copy of the object under a brand new session using the ID of one of your originally created objects.
  • Call the "Matches" method to compare the two objects. (concern #1)
  • Verify that the IDs of the parents/children of the original object equal the IDs of the parents/children of the loaded objects (concern #2)
Finally, tear down the database at the end.

Labels: ,

Wednesday, November 28, 2007

Open source enterprise sample using ActiveRecord

On the 29th, Ill be working an ACM lecture at UNH on the life of a computer consultant.

Something that is important to me: code speaks louder than words. Its cool to hear new ideas, new philosophies, but coded examples of these ideas backs them up with a little reality. The problem is, its hard to give code examples without lots and lots of surrounding context to make the code real.

I put together a new open source project on google code. It is a "zen-garden" style project for enterprise-level data applications using Castle ActiveRecord under the hood. I kick-started this project by giving it a foundation, a domain, some controllers, and a web-based user interface. Now it has some critical mass. The application itself is not important so much as the ability to practice and learn new skills by playing with the code.

This is the link to the code project homepage. Be sure to view the project wiki for the nitty gritty details. This is the link to the subversion trunk. To download and run the application you will need:
Downloading the Project Code
If you don't want to join the open source project, you can simply download the app from the download tab. Make sure you have winrar or some rar extractor equivalent.

Joining and Contributing to the Project
  1. Contact me and I will add you to the project as a user, so you can reside under the subversion source control system. Dont be shy, I promise I will get you everything you need.
  2. You need to get a google account. If you have a gmail email address, you have a google account. If you don't, then go and register. (Google accounts are very worthwhile to any internet-junkie like myself)
  3. Select a folder where you want to download the code.
  4. Using tortise svn, right click on the selected folder, and select ToriseSVN--Checkout


use this url for the project when prompted:
https://activerecordenterprisesample.googlecode.com/svn/trunk/



You will be prompted for a username. Use your google account username.
You will be prompted for a password. Use the google code password I gave you.
With that, you will become an active member of the project.

Getting the code to run
  1. Look at the EntityLayer project. Modify the App.config file, be sure to set the sqldialect so it matches your database. Modify the connectionstring so it can reach your database.
  2. Open the DatabaseSetup.cs class. See the test that creates an empty database? Execute it using testdriven-net by right-clicking on the [Test] keyword. This will create your database.
  3. Once this works, modify all of the *.config files in the project in the same manner.
  4. Set the WebLayer as the startup project, by right clicking on the project in the solution explorer. Hit F5, and you should have the website up and running.

Labels: , , ,

Tuesday, November 27, 2007

NHibernate:How to Build Great Mappings and use SchemaExport

NHibernate.Tool.hbm2ddl.SchemaExport: this thing is so cool its not even funny.

Consider the following code:

SchemaExport _schemaExport = new SchemaExport(new Configuration().Configure());
_schemaExport.Create(false,true);

Do you know what that does? It builds a database schema from the mapping files! The first parameter is an option to output the script to the console. The second parameter is an option to execute the script in the database.

All you need is an App.config such as:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>

<!--nhibernate configuration-->
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<!--the brand of dbms-->
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<!--connection provider-->
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<!--sql client driver-->
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<!--connection string-->
<property name="connection.connection_string">Server=localhost; initial catalog = YOURDBNAME; Integrated Security=SSPI</property>
<!--output generated sql to console window-->
<property name="hibernate.show_sql">true</property>
<!--the assembly with the embedded mapping files-->
<mapping assembly="[YOURASSEMMBLY without the .dll ectension]" />
</session-factory>
</hibernate-configuration>
</configuration>

If you don't have sql server 2005, change the dialect; NHibernate supports 99% of the popular modern databases. These are the steps you need:
  • Create an empty database using your DB server
  • Create NHibernate entities, create the mappings
  • Add the app.config listed above
  • Execute the code listed above
And there is your database. If you want to drop it at the end, simply call _schemaExport.Drop.

Do you know what this means? It means that my XML mapping IS my database schema.
You dont need to synchronize the database schema from the mappings if your database schema is CREATED FROM THE MAPPINGS!

If your mappings are the de-facto definition of your database, then you better have a very high degree of control over the database being built. Let's dissect a mapping file that is very conscious to database concerns:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" default-cascade="all-delete-orphan">
<class name="acme.widget, acme" table="Widgets" >

Notice how you can set the default-lazy and default-cascade behavior of NHibernate on the class declaration? They define the general behavior of NHibernate in terms of loading objects and saving them, and changing these settings changes the behavior of your program considerably. Learn more about these settings here and here.

<!--primary key mapping-->
<id name="m_id" column="WidgetID" type="int" access="field" unsaved-value="0">
<generator class="identity" />
</id>
See the unsaved-value=0? This means any Widget object with an ID of 0 warrants an insert call when using the SaveOrUpdate method. Any Widget object with a nonzero ID warrants an update call. See the access="field"? This gives NHibernate the permission to manipulate the ID field through a private variable. This way, you don't need to expose the ID of an object as a public writable property.
<!--property-to-column mappings-->
<property name="WidgetName" not-null="true" type="string" length="30" unique="true" unique-key="myCustomUniqueKeyName" >
<column name="WidgetName" sql-type="varchar(30)" not-null="true" index="myCustomIndex" unique="true"/>
</property>
See how I add a <column> tag? the column tag gives me specifics about the sql data type of the column, the index, and allows me to set a named unique-constraint on the column (enforced by the database).
<!-- Many To One Relationships -->
<many-to-one name="Factory" column="FactoryID" not-null="true" not-found="exception" class="acme.Factory, acme" index="myIndex" foreign-key="myCustomFKName" />
</hibernate-mapping>
In here I explicitly named an index on this column called "myIndex". SchemaExport automatically builds the foreign key constraints for me, but I can give it my own name 'myCustomFKName'. I forced the property not to allow nulls (rarely do you need nulls) and to throw an exception if, for some reason, the relationship is broken. Redundant, perhaps, but there is nothing wrong with some redundancy to ensure the integrity of the model.

Using this kind of database-conscious mapping technique allows you to build a quality schema automatically from SchemaExport. I have challenged this SchemaExport with difficult schemas, single-table inheritance mapping, multi-table inheritance mapping, many-to-many mappings, and it never falls short.

Almost never. Here are a few examples where this is not enough:
  • Views, UDFs, stored procs and all of those other non-NHibernate related database objects
  • I want a clustered index on a foreign key, so all of the "child" rows are arranged physically adjacent with respect to the parent rows for faster disk access
Fortunately, SchemaExport gives us a great all-around solution for these kind of custom database concerns using the database-object tag...
<database-object>
<create>create view ....</create>
<drop>drop view....</drop>
</database-object>
You can also write a custom class to create the database object by implementing the NHibernate.Mapping.IAuxiliaryDatabaseObject class.

<database-object>
<definition class="MyViewDefinition, acme"/>
</database-object>


This also works for different dialect scopes using the dialect-scope parameter if you need to support different dbms's. all of this information can be found at the bottom of this page.

Bottom line is, the SchemaExport tool is a great shortcut to getting a database up and running from ntohing but the object code and some mappings. To upgrade the schema of existing databases without loss is still a tricky procedure, but this is great for things like:
  • Unit tests (destroy and rebuild a fresh data population with every test)
  • Early application development lifecycle (where the schema definition is in a high state of flux)
  • setup/deployment - creating a database schema within a setup deployment installation program is a snap with this tool

Labels: ,

Wednesday, November 21, 2007

C# Short-Hand Tricks

Nothing earth-shattering, but this is a list of some of the lesser-known wrist-friendly shortcut features in the C# 3.0 compiler (and one that has been around for awhile).
These features are cool, because they all make the code smaller and easier to read, without adding perl-style cryptic confusion and making us a contender in any code obfuscation contest.

Coalesce
How often do we write something like this:

object outerObject = null;
...time goes by....
object innerScopedObject;
if (outerObject == null)
innerScopedObject = new object();
else
innerScopedObject = outerObject;

or

object outerObject = null;
...time goes by....
object innerScopedObject = outerObject ==null? new object();

with the coalesce operator (double question mark) '??' the following statement is equivalent:

object innerScopedObject = outerObject ?? new object():

Its nice, because the coalesce operator is specifically for handling null cases.

Automatic Properties
How often do we write something like this:

private int foo;
public int Foo
{
get { return foo; }
set { foo = value; }
}
The point is, you are encapsulating a private variable just to expose it via a property without any accessor logic. In C# 3.0, the following statement is equivalent:

public int Foo
{
get;
set;
}

The compiler will automatically generate the private variable for you. One less variable to worry about; less code is better code.

Nullable Primitives
(This trick has been around for awhile now) Ever needed to do this:

DateTime dt = null;

Just to find out it won't compile? Why is it they give us a database that allows for nullable integers and DateTimes, but a C# language that forbids it?
The 'nullable' operator (the question mark operator) '?' lets this work.

DateTime? dt = null;

That will compile. Don't get carried away with that trick; null can mean so many different things. Truth is, it is VERY rare when null values are handy in terms of database persistence.

Labels:

Friday, November 16, 2007

C# Generic conversion/grouping tricks

Note: none of this is new, it is just new to me.

I used to love C, for its speed and flexibility. I learned to love C# for its exception handling features. To me, the real killer feature of C# 2+ is the generics. It is undeniably easy to understand and makes my work profoundly easier.

One of the problems I have been having with generics is when I need a List<K> when I really need a List<T>. I stumbled upon the generic Converter class (finally) which makes life much easier for these scenarios.

This code builds a collection of floats and uses a delegate to convert it in to a collection of ints
        
public void Testx()
{
List<float> _floats = new List<float>();
_floats.Add(1f);
_floats.Add(11.5f);
_floats.Add(12f);
_floats.Add(1.1f);
_floats.Add(55f);
_floats.Add(124f);
_floats.Add(127.2f);
_floats.Add(6222f);

List<int> _ints = _floats.ConvertAll(ConvertFloatToInt);
}
public static int ConvertFloatToInt(float x)
{
return Convert.ToInt32(x);
}


Cool, but what if it is not a true one-to-one conversion between the source type and the target type? I mean, what if a bunch of Ks convert in to a common T? How about a grouping method?
This code takes in a collection of the source type, a converter, and returns a dictionary of the target type as keys, and collections of the source type as grouped values.

public static IDictionary<T, ICollection<K>> GroupBy<K,T >(ICollection<K> collection, Converter<K, T> converter)
{
Dictionary<T, ICollection<K>> _dictionary = new Dictionary<T, ICollection<K>>();
foreach (K k in collection)
{
T key = converter(k);
if (_dictionary.ContainsKey(key) == false)
{
_dictionary[key] = new List<K>();
}
_dictionary[key].Add(k);
}
return _dictionary;
}
public static int ConvertFloatToMod10Int(float x)
{
return Convert.ToInt32(x % 10);
}
[Test]
public void Testx()
{
List<float> _floats = new List<float>();
_floats.Add(1f);
_floats.Add(11.5f);
_floats.Add(12f);
_floats.Add(1.1f);
_floats.Add(55f);
_floats.Add(124f);
_floats.Add(127.2f);
_floats.Add(6222f);
Converter<float, int> _converter = new Converter<float, int>(ConvertFloatToMod10Int);
IDictionary<int, ICollection<float>> _dictionary = GroupBy(_floats, _converter);
}

Now this generic GroupBy method is going to be very handy in the future, especially since the delegate will dictate the behavior of the converting/grouping functionality.

Lets take this one step further: what if every K converts in to a collection of different Ts? Then we will need a "Fan Out" function (very handy for genetic algorithm processing, it turns out):








public static IDictionary<K, ICollection<T>> FanOut<K, T>(ICollection<K> collection, Converter<K, ICollection<T>> converter)
{
IDictionary<K, ICollection<T>> _dictionary = new Dictionary<K, ICollection<T>>();
foreach (K _k in collection)
{
ICollection<T> fan = converter(_k);
_dictionary.Add(_k,fan);
}
return _dictionary;
}

Labels: