2009-09-25

The beauty of 2 state enums

The .NET type system already has a type for 2 states, it is of cause the Boolean. So why would I want to make a custom type?

Lets look at some code.

   1: var export = new SchemaExport(_cfg);
   2: var sb = new StringBuilder();
   3: TextWriter output = new StringWriter(sb);
   4: export.Execute(true, false, false, null, output);

The code above is from NHibernate, more specifically it is NHibernates schema export.

The documentation looks like the following.

public void Execute(bool script, bool export, bool justDrop, System.Data.IDbConnection connection, System.IO.TextWriter exportOutput)
    Member of NHibernate.Tool.hbm2ddl.SchemaExport

Summary:
Executes the Export of the Schema in the given connection

Parameters:
script: true if the ddl should be outputted in the Console.
export: true if the ddl should be executed against the Database.
justDrop: true if only the ddl to drop the Database objects should be executed.
connection: The connection to use when executing the commands when export is true.  Must be an opened connection. The method doesn't close the connection.
exportOutput: The writer used to output the generated schema

Remarks:
This method allows for both the drop and create ddl script to be executed.  This overload is provided mainly to enable use of in memory databases. It does NOT close the given connection!

Now I don't necessarily remember method signatures all to well. So custom type too the rescue, or rather custom enum too the rescue.

   1: public enum Script
   2: {
   3:     OutputToConsole,
   4:     NoConsoleOutput
   5: }
   6: pulic enum Export
   7: {
   8:     ExecuteScriptAgainstDatabase,
   9:     DontExecuteAgainstDatabase
  10: }
  11: public enum DDL
  12: {
  13:     DropOnly,
  14:     CreateAndDrop
  15: }
  16: export.Execute(Script.OutputToConsole, Export.DontExecuteAgainstDatabase, DDL.CreateAndDrop, null, output);

Another alternative is to make several methods that can be named, or create a class that takes the arguments as properties, so that they can be optional.

2009-09-23

Using NHibernate and SQLite on x64

If you are using a x64 OS, and have a reference to System.Data.SQLite and NHibernate throws exceptions like these:

  • NHibernate.HibernateException : Could not create the driver from NHibernate.Driver.SQLite20Driver, NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4.
  • NHibernate.HibernateException : The IDbCommand and IDbConnection implementation in the assembly System.Data.SQLite could not be found. Ensure that the assembly System.Data.SQLite is located in the application directory or in the Global Assembly Cache. If the assembly is in the GAC, use <qualifyAssembly/> element in the application configuration file to specify the full name of the assembly.

It most likely because SQLite is not a managed dll, it is compiled to a specific CPU.

System.Data.SQLite does not change this behavior since it is just a wrapper and container for the unmanaged dll.

The easiest way to fix this is to change the platform target under build properties of the Visual Studio project to x86.

VSProjectPropertiesBuild

Another alternative is to choose the x64 version of System.Data.SQLite, but if the same source code is used on both x86 and x64 it is not option.

2009-05-22

Data, objects and abstractions – Are there more to DIP?

If we define the following:

Data is just raw data, with no context and no logic associated.

Objects contains both data and behavior that operates on that state.

Abstractions defines behavior by naming, with out any details of how the desired behavior is implemented.

 

A common definition of DIP states that:

High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.

That keeps the objects from referencing each other, creating low coupling = a good thing :-)

In C# code following DIP, there is often an “IFooBar” and a “FooBar”. So we have a 1 to 1 between abstractions and object classes. I never really liked it, I don't know why it just don't feels right. Another side effect is that objects that depend on the abstraction can now be unit tested, but often we need to mock the abstraction. In my opinion this leads to hard-to-read and brittle tests.

Is there a simple alternative?

So if objects should not depend upon other object and an abstraction is not desirable, what should the dependency be?

Data

It just like messaging between systems, only this is inside an system. Instead of having a direct dependency to the “CustomerRepository” or having to create a “ICustomerRepository”, just depend on a Customer or a Customer[], nice and simple. This assumes that the Customer is data, and not a object or abstraction.

Move as much if/else/switch/loop code to object classes that depend on and creates data, that way they are easily read, tested and understood. As close to the user action (button click etc. – I call them “Controllers”), get the data needed(possible from a database), pass it to or create the objects, and then take action based on the data result(SubmitChanges to the database, send the MailMessage or what not). These “Controllers” are hard to test and need mocking because of all the database work, mail sending etc., so here classic DIP applies. The Controllers should have a minimum of conditional statements (if) and the few if statements needed should not be nested. This is extremely procedural in nature, and is easy to read.

 

Sometimes we actually need an abstraction, and by all means make one. But code reads better when it just data flowing through logic.

2009-02-19

Combo box vs Button

I don't know exactly why, but I almost never use combo boxes/drop-down liste etc.

If we have an order with an order status, where order status can be cancelled, pending, approved and shipped.

I often see screens like this:

comboboxvsbutton1

The screen makes sense for most developers because that is how the data i structured in the database, usually with an Order and OrderStatus table.
In code this is mapped to an Order class and an OrderStatus enum, where the Order class has a Status property with the type of OrderStatus.

So its easy with data binding to make every property a field in the screen, and most data binding will happily make enum properties to combo boxes.

What does the user want to do

So how can we express the order status without a combo box?

Actually the question is not hard to answer, just try to understand what the user really wants.
”A user wants to be able to change the order from a status, to any status that is valid.”

In the above case, most likely not every order status is valid from all other order statuses. So its ok to go from Pending to Approved, but not from Shipped to Pending.

So the key is, to only show valid changes in order status, and to make the user able to trigger these changes.

A solution could look like this screen:

comboboxvsbutton2 

Conclusion

While simple data binding is easy to do in most platforms, it might not be the best solution – from a users perspective.