Ayende @ Rahien

It's a girl

Ideas for a sample application?

I'm seeking ideas for a sample application to demonstrate the capabilities of Rhino Commons. Anyone has suggestions?

It should be geared toward showing the benefits of using this approach, and yet simple enough so it wouldn't take too long to create. And I am kinda sick of bug tracking systems.

Tags:

Published at

Introducing the NHibernate Query Generator

Okay, it looks like I can track down fairly easily what books I read, when I read Working Effectively with Legacy Code, I wrote Rhino Mocks. Now I am reading Applying Domain-Driven Design and Patterns, and I wrote the NHibernate Query Generator.

So, what is this all about?

NHibernate has two major API for querying objects. The first one is called the query API, and uses HQL, a language similar to SQL but with OOP aspirations. The second is called the criteria API, and it is far simpler API, but it is also much easier to use.

Here is a simple example of using the criteria API using my Repository sample from yesterday:

ICollection<Customer> customersInLondon = Repository<Customer>.FindAll(Expression.Eq("City""London"));

Now, those of you that already knows me know that I have a passionate dislike to strings. I wrote a mock objects library because of this issue, so I may need physcological therapy in the future, but I hate strings.

Well, what do I do when there is something that I don't like? I fix it.

In this case, there where two main options, run time proxying and code generation.

Run time proxying is similar to what I do in Rhino Mocks, and it may look like this:

ICollection<Customer> customersInLondon = Repository<Customer>.FindAll(Expression.Eq(Expr.Of<Customer>().Name,"London"));

This has the disadvantages of being both ugly and complex, so I turned to the other route. I build a small application which takes an NHibernate mapping file (hbm.xml) file, and output a strongly typed query wrapper. The above query can now be used like this:

ICollection<Customer> customersInLondon = Repository<Customer>.FindAll(
   Where.Customer.City.Eq("London") );

This is much better, and of course that you get all the other nice things about the expression API (like Between, In, etc).

You can get it here, binaries only. Source would have to wait for a while, my subversion provider has run out of room. Note that the code it generates relies on a class called NamedExpression. The class is included in the binary, so just add it to your project and you are done.

I also added support for queries, since I didn't want to leave the other side of the API high and dry, it means that you can do this:

ICollection<Customer> customersInLondon = Repository<Customer>.FindAll(
    Queries.AllCustomersInCity, new Parameter("city""London"));

Here is a little FAQ

  • What does it generate:
    The tool generate strongly typed wrappers for each of the mapped entities and each of their properties. At the moment, is supports querying against properties, many-to-one, and ids.
  • How to make it work for all the files in a directory?
    Simply use the batch capabilities of the shell, like this:
    for %f in (*.hbm.xml) DO "NHibernate.Query.Generator.exe" %f D:\Queries
    This will run the tool over all the files in the directory, and output them all to the Queries dir.
  • How to make it work with ActiveRecord?
    You need to use the isDebug="true" flag in the configuration, and then point the tool to the resulting mapping files.
  • Can I get is as a custom tool for Visual Studio?
    It shouldn't be hard to do, but I don't have the time at the moment. Feel free to send me a patch for it when I release the code.

Rhino Commons In The Open

I just realized that I was posting about it all day, but I forgot to mention where you can get it.

You can browse the source repository online here, or get the source using:

 svn checkout svn://svn.berlios.de/rhino-mocks/trunk/rhino-commons

IoC and fluent interfaces

You may have noticed that I like to play word games with code, so here is the Inversion of Control interface in Rhino Commons:

(Image from clipboard).png

The main goal is to be able to say:

ISender sender = (ISender)IoC.Container.Resolve("email");

The Initialize() method is called at application start, and will set everything up for the rest of the application. This class is to fetch the repositories, so I can generate a complex object graph and handle some interesting scenarios from the start, using generic decorators.

In the end, I didn't go with NHibernate / Transaction integration, for the simple reason that the Repository<T> and With.Transaction{} made them unnececary.

On Open Source

You probably have heard that NDoc's lead developer, Kevin Downs, has announce that the NDoc is Dead. It also came up in the NHibernate devel mailing list, mostly as questions as to the viablity of open source.

I can't tell why other people are working on OSS, some do it for fun, others because it gives them tools or advantages for later on. It is rare that people are getting paid to work on Open Source Software. I know that I started this to sharpen my skills, and right now I am doing this because I like it and because it gives me the chance to do things that I like doing.

I am involved in a number of OSS projects, so I feel that I speak from experiance here. There are no guarantees of the amount of time that an OSS will go if you are not willing to invest time/money in it. If you do, you can either invest your time in fixing bugs, and send the patches to the project, where they are likely to be accepted.

The best way to influence the development of a product is to say what you want, and either help make it happen, or agree to pay for it. Even if your needs will not always fit the mainstream (you want to support NeverHeardOfDB, for instance) release, it can usually be fitted as a native extention to the product.

So, to cut it short, complaining about not getting what you want is not really going to help. You are getting your money's worth.

Tags:

Published at

More on repositories

I forgot to add that I am using a static forwarder class to get a better syntax, so I have this (after the change from RegisterSave()/RegisterDelete() to Save()/Delete() ).

(Image from clipboard).png

Another thing that I wanted to talk about was the FindAll()/FindOne() methods. While they have their overloads for working with ICriterion (and wait for a surprise there too), they also have overloads for queries.

Now, I believe that one of the responsabilities of good API is to encourage good code, so I don't have any overload which accept a literal query, instead, all the overloads accept the name of a named query, and its parameters.

Thinking About The Repository API

I'm currently building the API for the my Repository interface (I talked about it here). Here is what I have so far:

(Image from clipboard).png

Couple of things to note, I don't have Delete or Save methods, instead, I use RegisterSave() and RegisterDelete(), both of those make it clearer that a Unit Of Work is in action here. To make it more explicit (and to allow several repositories to use in a single Unit Of Work, I made the Unit Of Work an explicit concept:

(Image from clipboard).png

A sample code using this framework will look like this:

using (UnitOfWork.Start())

{

    With.Transaction(delegate

    {

        Customer customer = Repository<Customer>.Load(15);

        Order order = new Order();

        customer.Orders.Add(order);

        Repository<Order>.RegisterSave(order);

    });

}

Looking at the code, I don't know if RegisterSave() gives anything, to tell you the truth.

I'm using the commit only flush mode with NHibernate, which mean that if you are not commit the transaction, it will not be saved to the database. The problem is that then all my writing to the database will be inside a With.Transaction() block, which mostly make the Register***() mote.

TDD Challange

How would you go about testing code that generate code? I can think of only those two approaches:

  • Compare strings - very fragile.
  • Compiling the generated code and test that - may be complex if what you are generating is basically helper code.

Anything else?

Lectures Arsenal

I am currently building a "lecture arsenal", which means that I should have a set of lectures that I can give at a moment notice. The idea came from Justin, who usually walks around with a portable projector, so he literally can be in the middle of a talk and start saying: "You know, I have a lecture of that. Give me three minutes and we can start" :-)

What I have at the moment is the following:

  • Inversion of Control & Dependency Injection - Introduction
  • Inversion of Control & Dependency Injection -
  • Using Mocks For Testing – Basic
  • Using Mocks For Testing – Advanced
  • Introduction to Object Relational Mapping – Nhibernate & Active Record
  • Building a web site using Active Record
  • Complex scenarios for using OR/M - Taking design patterns into the database layer.
  • MonoRail: An MVC web framework for .Net

Anything else that you think that I am qualified to talk about? I thought about:

  • Ranting about things that I don't like in ASP.Net

But I don't think that this will be a very good one :-)

Tags:

Published at

Polymorphic Databinding Solutions

Let us assume that you have the following class hierarchy:

(Image from clipboard).png

Now, what do you think the result of this code will be?

BindingList<Animal> animals = new BindingList<Animal>();

animals.Add(new Dog());

animals.Add(new Cat());

GridView gridView = new GridView();

gridView.DataSource = animals;

gridView.DataBind();

Ten points goes to the lady on the right that said that it will produce the following error:

Unhandled Exception: System.Reflection.TargetInvocationException: Property accessor 'Name' on object 'AnimalDesc.Cat' threw the following exception:'Object does not match target type.' ---> System.Reflection.TargetException: Object does not match target type.

The reason for this bug is that the TypeDescriptors in .Net are not aware of polymorphism. Even though both Cat and Dog inherit from Animal and has a Name property, and that the list that I passed to the DataSource is BindingList<T>, the TypeDescriptor only looks at the first item in the list, and uses it to describe all types in the list. This can cause problems when the collection that you pass to the GridView contains an inheritance hierarchy.

After butting my head against this issue for too long, I finally came up with this solution:

public class AnimalTypeDescriptionProvider : TypeDescriptionProvider

{

    public AnimalTypeDescriptionProvider() 

        :base(TypeDescriptor.GetProvider(typeof(Animal)))

    {

    }

 

    public override Type GetReflectionType(Type objectType, object instance)

    {

        return base.GetReflectionType(typeof(Animal), instance);

    }

 

    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)

    {

        return base.GetTypeDescriptor(typeof(Animal), instance);

    }

   

    public static void Register()

    {

        TypeDescriptor.AddProvider(new AnimalTypeDescriptionProvider(), typeof(Animal));

    }

}

Then, I call the AnimalTypeDescriptionProvider.Register(); method in the start of the application.

What this does is it lies to the data binding infrastructure, and tells them that any type that inherits from Animal is actually an Animal, and should be treated appropriately.

This solution is good enough for now, but it will prevent me from databinding a list of Dogs, for instance.

Tags:

Published at

Fixing log4net 1.2.9 AdoNetAppender NULL bug

In log4net 1.2.9 there is a bug in the AdoNetAppender. It will not log null values appropriately. This bug is fixed in log4net 1.2.10, but it is not always possible to move to the next version. (In my case, both NHibernate and Castle uses log4net 1.2.9)

I tried recompiling everything to use 1.2.10, but it took too long, and eventually I simply wrote this little trigger:

CREATE TRIGGER [ReplaceNullLookAlikeWithNulls]

   ON  [dbo].[Logs]

   INSTEAD OF INSERT

AS

BEGIN

      -- SET NOCOUNT ON added to prevent extra result sets from

      -- interfering with SELECT statements.

      SET NOCOUNT ON;

 

   INSERT INTO .[dbo].[Logs]

           ([Date]

           ,[Thread]

           ,[Level]

           ,[Logger]

           ,[Message]

           ,[Exception]

           ,[Filename]

      SELECT

              [Date]

              ,[Thread]

              ,[Level]

              ,[Logger]

              ,[Message]

              ,[Exception]

              ,case [Filename] when '(null)' then NULL else [Filename] end

       FROM Inserted

END

Not the best solution, but it will hold water.

Empty Headed

I am reading this WTF and cringing, but what prompt this post is this comment:

I worked for a place that liked to test new candidates to better gauge if they were the ‘right stuff’.  One of the tests was to put the person in front of a computer and have them write a couple of apps.  One of the apps was to write a sort algorithm, and it could be any sort algorithm.  Clearly anyone who could implement a bubble sort was the ‘right stuff’ (sarcasm)

Hm, I don't think that I can come up with any other sort algorithm on the fly at the moment (at the moment being 00:15 AM at my place). To be truthful, I probably couldn't come up with any other sort algorithm in 9:00 AM either.

The last time that I had to that was in class, and I'm pretty sure that what I did there is topped by the BCL, STL, etc algorithms. Beside, we all know that mergesort is broken. Are those the criteria that people are hiring on?

I can find a good answer in google in about 5 seconds, better yet, I can take my anti-NIH pill and use Array.Sort() (or one of its contemporaries). Is this really what people are asking in interviews? Next they will ask how to copy a file *.

If it not crucial, I don't bother to keep it in my head. There isn't any point, I have limited time and limited ability to digest things, I have better things to do with my time them memorizing things that can be searched. Hell, one of the reasons that I have a blog is that I can refer to it in the future and find the solution to issues that I already solved. Hell, I wrote dozens of SQL Functions, and I still don't remember their syntax.

Why bother asking such questions when 99% of the time the developer is not going to start developing data structures?

My current favoraite question is to solve the Recommend a Product based on the Recent Order riddle. I solved that one (for fun, actually, not for work) in 13 lines of SQL. I like it because it is relevant to what most people will do (although I aim to keep away from the database, I keep getting pulled there :-) ), and it is not something that can be trivially solved by memorizing.

I am actually not interested in the correct answer, that one is too hard to solve on the spot in an interview, but more at how they approach the issue. I got a few good answers on the fly, just talking through the connections between the tables, which was exactly what I wanted to hear.

One of the best interviews that I had was with a developer that answered wrong to most of my questions, but I could see that he thought, and that is so much more important than a head full of data structures and language syntax is.

Oh, and if anyone who is reading this is going to be interviewed by me, don't chear about the solution to the above riddle. The nextx one in the ladder is called Multi Threading Madness :-)

* I am not a good example for this case, it takes me 12,259 lines of code to read a file :-)

Tags:

Published at

Useful blogging

I wrote this comment last week over a piece of code:

/// <summary>
/// Yes, this is ugly.
/// Yes, we need fix it.
/// If you read it, take the time to do it yourself.
/// We believe is shared code ownership, you are welcome.
/// </summary>

I knew that I would want to blog about it, and I knew that I couldn't do that until I fixed the code.

That is useful.

MonoRail Generator

Take a look at this, very awesome.

It is still alpha/beta, but it looks just amazing.

Tags:

Published at

Code Monkey Video

A couple of weeks ago, the Code Monkey song made the rounds.

Now there is a video, and it is hilarious!

Tags:

Published at

Debugging NHibernate: A Waste Of Time :-D

Sigh. It looks like I won't be able to fix the bug that I thought to fix. Someone fix it already. I have grown attached to this bug, in the short time that I knew it, but I guess that it is the way of life, bugs come and go.

If anyone is interested, it has to do with deleting an item from a collection that is cached on the second level cache, and then accessing the previous owner of this item from another session. Repreducable in 1.0.2, fixed in 1.2.0 alpha.

Tags:

Published at

Deep Diving Into NHibernate: The Tests Structure

Just a quick note before continuing. In NHibernate, most tests inherits from the abstract NHibernate.Test.TestCase class. This class is responsible for the infrastructure of the test. By that I mean that it instansiate a Session Factory, create the appropriate tables, etc.

A test fixture specify how to find its mapping using these two properties:

/// <summary>

/// Mapping files used in the TestCase

/// </summary>

protected abstract IList Mappings { get; }

 

/// <summary>

/// Assembly to load mapping files from (default is NHibernate.DomainModel).

/// </summary>

protected virtual string MappingsAssembly

{

      get { return "NHibernate.DomainModel"; }

}

Creating a session is done by calling the protected method OpenSession().

This frees the tester from dealing with all those issues. (Just automatically creating the tables is a huge burden of my chest).

One important thing to note is that NHibernate expect the test to clean up after itself. It should close the session, delete any data that you put in the database and close any connections that you have opened.

If you are interested in modifying the configuration (as I did, to add support for second level caching), you can access the base.Cfg variable, and modify it, and then generate a new session factory from that.

That is enough details for now, I think.

Deep Diving Into NHibernate: The Second Level Cache

I mentioned before that I am now part of the NHibernate project, but so far I haven't done much with it. In what turns out to be a nice timing, I found a fairly obscure bug that I hope that I can fix, and I am going to bore you with all the nitty gritty details of how I am going to do it.

Before I can begin, let me describe what area I am going to work at.

NHibernate has two level of caches. The first level is the session, which holds all the entities that were loaded (or saved) with the session. This cache is not shared among threads/requests. This cache hold the objects as fully instansiated entities, which mean that sharing them among threads/requests will cause multi threading issues.

The second level cache is shared among all the session that were created from the same session factory (typically, you only have a single session factory per application, so in essense, this is an application level cache). There are several targets to this second level cache, but the most common are:

  • Hashtable cache (for debugging/testing purposes only)
  • SysCache - which utilize the ASP.Net Cache
  • Memcached - a distributed caching system

The second level cache does not hold entities, but collections of values. This means that you don't have to worry about mutli threading issues when you use this cache.

As far as I can see, the second level cache isn't very utilized in NHibernate projects, although I am not quite sure why this is the case, since it can give quite a performance boost to an application, without affecting the client code.

C# Compiler Generating Invalid IL When Dealing With Generics

I just had to find out the reason for a strange bug in Rhino Mocks. The issue turned out to be the C# Compiler producing invalid IL, which cause the following error:

failed: System.BadImageFormatException : An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

Let us start from the beginning, here is an interface and a class:

public interface MyInterface

{

}

 

public class MyGenericClass<I>

{

}

Now, let us define the following test:

public abstract class TestGenericPartialMockBase<I, C> where I : MyInterface where C : MyGenericClass<I>

{

       public void CauseProblem()

       {

              bool val = false;

              if (val)

              {

                     Factory factory = new Factory();

                     object bad = factory.Create<C>();

              }

       }

}

 

[TestFixture]

public class TestGenericPartialMock1 : TestGenericPartialMockBase<MyInterface, MyGenericClass<MyInterface>>

{

       [Test]

       public void TestGenericPartialMockTest1()

       {

              CauseProblem();

       }

}

Notice that the code in the if() clause will never execute, its mere precense cause this error.

The Factory class is simply:

public class Factory

{

       public T Create<T>(params object[] args)

              where T: class

       {

              return null;

       }

}

Put everything in one file and try to run the test, and it will give the error above.

Removing the "where T: class" clause from the Create<T>() method will fix this issue, as well as practically any modification to the code. This is the second time in about three weeks that I see the C# compiler silently issuing invalid IL for complex generic scenario. Interestingly, both scenarios involved inheritance from a generic class.

Update: You can vote on this bug here

Tags:

Published at

An Answer To Remember

I frequent some of the programming forums in Tapuz. Justin has decided to answer a question there that cracks me up every time that I read it (5 - 6 times so far).

The question was why "Dim objRegex as Regex" gave an error, by the way. I have no idea if it will be as funny in English, but here is Justin's answer:

Have you considered reading the error message?

It tells you "I don't have any idea what is this Regex thingie that you are talking about, but maybe it is this thing Regex that sits in System.Text.RegularExpressions. So if you want to use this Regex that you keep mentioning, then either put Text.RegularExpressions.Regex or just put a reference at the top of the page that would tell me to always looks into System.Text.RegularExpressions.

In the meantime, I will just sit here quitely, in the dark, incide you CPI. There isn't much to do.

Oh, look, a bit."

That is more or less what the compiler is try to tell you :-)

Tags:

Published at

On The War

I would like to point you to this (Lebanese) blog.

Perhaps the best description of the current situation in both Israel and Lebanon is here. (To the geography challanged, Nahariya is a city on the north of Israel).

And this is unquestinonally the best commentry I have seen or heard about the current crisis.

TDD Worst Practice: Test Driven Debugging

I saw this trend at a few of my clients. The use of NUnit tests not as a way to drive the design or verify that the code works, but as a cheap way to setup the code into the conditions that they needed, and then debug through the code, to verify that it works. This is often used in the beginning of the project, where there isn't enough UI to drive the functionality of the code.

I tend to do the same when I try things, or want to verify something, so broadly, I don't have an issue with this approach to solve issues. TDD urge you to build tests before you fix bugs, but this isn't it. And I can certainly understand the need to explore code that doesn't have any UI, but these tests violate just about every rule of TDD that they can (not repeatable, not meaningful, highly order dependant, data dependent, etc).The bad part here is that those teams check the tests into the source repository, and some of them thinks about them as a real tests.

Wish: Assembly Redirection For The Compiler

We have assembly redirection for compiled assemblies, but is there such a thing for the compiler?

Spesifically, my problem is replacing a production version of a dll with a modified debug version, and then runing that. The issue is that I can't use the production dll and then replace it for debugging + assembly redirect, since on of th dll has a dependency on that modification.

I solved that issue by recompiling everything against the debug modified version, but that is a PITA. Is there a better way?

The problem right now is that the compiler will complain about mismatch types (can't convert from Foo.Bar to Foo.Bar), because they are of difference assemblyes.

Tags:

Published at

Harvesting For Frameworks

It is getting to that point in again where I find that I am writing the same code in several projects, and I get tired of that by the third repetition. It is time to harvest those projects for reusable pieces. At the moment I am planning on making this a part of Rhino Commons (what can I say, I like my Rhinos :-) ).

Currently I am planning the following additions:

  • Extentions to Windsor that includes:
    • Configuration Objects
    • Builtin NHibernate Integartaion and Automatic Transaction Management
    • Maybe: Add dependency cycle tracking (if it can be done externally).
  • IRepository<T> interface as well as a static class
  • NHibernate Repostiory<T> implementation
  • Repository<T> access point which will forward all calls to a repository instance that it gets from Windsor
  • Persistable wrappers around NHibernate's Criteria API that will also support operator overloading
  • Utility mehtods like ToArray<T>(IList), ToBindingList<T>(IList), etc.
  • With.Transaction( delegate { } )
  • More validations

If you can think of anything else that I blog about recently that you think would be nice to have there, drop me a line.

This also means that currently I'm taking a hard dependency on the following for all my projects:

  • NHibernate
  • Castle Windsor
  • log4net