Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 18 | Comments: 82

filter by tags archive

ChallengeWindsor Null Object Dependency Facility

time to read 1 min | 115 words

In Scott Bellware's post about dependency injection, he has a comment about optional dependencies:

Setter dependencies are optional.  Their types should have a Null Object pattern implementation, and if not it's often a good idea to decorate them with one.  For example, if an optional dependency hasn't been set, it might not be desirable to have a null reference exception when a method is invoked on it

The challenge is to provide a facility for Windsor that will detect an optional dependency and fill it with a Null Object (i.e, an implementation that doesn't do anything). It is safe to assume that all such dependencies are using interfaces.

Can you do it?

Supporting OSS in the .Net Space

time to read 2 min | 293 words

Jeff Atwood wants to donate 10,000$ to open source projects in .Net-land. Check the comments, they are very interesting. This raises the question of whatever monetary support is the best way to support OSS projects. I really appreciate Jeff's efforts, and I think that they would do wonders for the moral of the developers that gets the money.

However, I want to point out some other ways to contribute, just as important, if not more so, than money:

  • Contributing to the documentation:
    • Tutorials
    • Gotchas
    • How-to
    • Samples
    • F.A.Q
  • Participating in the community (forums, mailing lists, etc) - answer questions that you can, help other people when they run into problems
  • Evangelize the project:
    • Post about it
    • Talk about it
    • Help people using it 
  • Bug hunting - there is a respectful position for Bug Contributors - they help make the project better

Contributing code is important, but it is far from the only way you can contribute, and most OSS projects can do with more help in the above mentioned ways than code contributions. Documentation, in particular, is something that OSS projects usually lack at.

As a side note, I think that Frans Bouma has hit a key point in a comment there:

You come with an example where MS provides the source. Great example. The thing is though: that's NOT what should be changed. MS should work _together_ with open source projects started by others, outside MS, and make sure these project don't hit a wall because MS thinks they have to do their own copied version of the same project.

He has some other points in the discussion that I disagree with (choosing to go OSS vs. commercial offering) , but the point above is a very important one.

DSL Support for Brail

time to read 4 min | 732 words

First things first, Harris Boyce III has done all the work, my sum contribution to this feature has included some wild cheering from the side lines.

That said, this is one cool feature. Let us explore it.

There are a lot of people who consider anything resembling <html> tags to be a mess, associate them with ASP Classic mistakes, and reject them out of hand. I think that this is a mistake, but I gave up changing the whole world overnight, now I have busy formulating three steps plans that takes a week...

At any rate, consider this output:

<html>
	<body>
		<table>
			<tr>
				<th>Names</th>
			</tr>
			<tr>
				<td>Ayende</td>
			</tr>
			<tr>
				<td>Rahien</td>
			</tr>
		</table>
	</body>
</html>

How would we generate this output using Brail? The classic approach is:

<html>
	<body>
		<?brail
                       component Grid, {"source": names}:
                         	section header:
                                    output "<tr><th>Names</th><tr>"
                               	end
                             	section item:
                        	    output "<tr><td>${item}</td><tr>"
                           	end
                        end
?> </body> </html>

This works, but it not really Jump-Up-And-Down-All-Excited code. And, of course, some people faint dead away from having to deal with raw HTML, "Give me my components or give me death!"

Now, here is the DSL way of doing it:

<?brail
dsl Html:
	body:
		component GridComponent, {"source" : names}:
			section header:
				tr:
					th:
						text "Names"
					end
				end
			end 
			
			section item:
				td:
					text item
				end
			end
		end
	end
end
?>

And this baby produces the same output as the previous one.

Now, you are probably aware that I am not really fond of raising the abstraction level needlessly, so why is this a good thing? Well, because it means that you can now do stuff like this:

dsl.Register(atom)
dsl:
   feed:
       title:
           div:
               text "some content"
           end
       end
   end
end

And it will be able to produce semantically correct ATOM feed. (To be exact, it would be if we had an AtomExtension implementation to the new IDslLanguageExtension interface, which we currently don't have).

There are some quirks in the implementation, but it is a very cool direction to go to.

OR/M Challenge Screen Casts Delayed

time to read 1 min | 139 words

About two weeks ago I asked how I should handle the OR/M Challenge from Rob, I got a lot of positive responses about it, and I fully intend to produce at least one or two screen casts about the subjects, but after trying to find a window where I have both the time and inclination, I must concede that it will may take a while. Just to give an idea, an hour screen cast takes anything between three hours (best case scenario) to three days to make. Finding such a big stretch of time where I actually have inclination to code is challenging. Contrary to popular opinion, I actually do get tired of code at one point.

So sorry, but it is going to be a bit late. Well, at least it is still under budget :-)

Stories form the class room: Picking the target for BackgroundWorker

time to read 2 min | 248 words

I am teaching BackgroundWorker at the moment, and I gave two demos of using it, one with printing and one with the classic long request to the database.

For the student work, I needed to find another sample that I could give them. I tend to like reasonable examples, rather than Hello world ones. I build them the following code to excersize:

WebRequest req = WebRequest.Create("http://www.msdn.com/");

using (WebResponse response = req.GetResponse())

{

    string homePageHTML =

        new StreamReader(response.GetResponseStream()).ReadToEnd();

    textBox1.Text = homePageHTML ;

}

 

At first I tried Google, but that was too fast to be a good demo, msdn.com takes ~15 seconds to get everything from the server, good, solid reason for why we need scalable application.

Sigh, this is so wrong!

Answering Mats' Challenge

time to read 3 min | 494 words

Mats Helander has a challenge for OR/M developers, and Mats should know, since he is behind NPersist.

Go for the post for details, but basically it is loading all Customer->Orders->OrderLines graph in 3 statements or less.

Because I am a sucker for challenges, I implemented it with ActiveRecord. In Mats' terms, the code is so simple it hurts, and yes, I cheated :-)

internal static IList<Customer> LoadCustomersOrdersAndOrderLines()

{

    Customer[] customers = Customer.FindAll();

    Order[] orders = Order.FindAll();

    OrderLine[] orderLines = OrderLine.FindAll();

    foreach (Customer customer in customers)

    {

        customer.Orders = new List<Order>();//avoid lazy load when adding

    }

 

    foreach (Order order in orders)

    {

        order.OrderLines = new List<OrderLine>();//avoid lazy load when adding

        order.Customer.Orders.Add(order);

    }

 

    foreach (OrderLine line in orderLines)

    {

        line.Order.OrderLines.Add(line);

    }

    return customers;

}

 

Case Sensitive Optimization

time to read 2 min | 335 words

I am doing some optimization work lately, and I managed to take a page down to three DB requests per page load, but I couldn't get it to less than that, and it really annoyed me. The problem was that accessing a certain properly on an entity would cause a lazy load, even though I have explicitly told it to eagerly load that.

That was... annoying.

Eventually I got rid of all the "it can't be!" mentality and looked at what was going on, the problem was that I was looking for NHibernate bug. The problem was actually more subtle than that. Let us say that I have this scenario:

Post post = session
  .CreateCriteria(typeof(Post))
  .Add(Expression.Eq("Id", 15))
  .SetFetchMode("Status", FetchMode.Join)
  .UniqueResult<Post>();

Console.WriteLine( post.Status.Name );// should not cause lazy loading.

I looked at the result, and looked at the result, and couldn't quite figure it out. Eventually it dawned upon me that the Posts' table had the following data:

Id Content Status
15 Interesting... PUBLISHED

While the PostStatuses table had this data:

Id Name
Published Published
DRAFT Draft

Do you see the problem? While NHibernate has correctly loaded the associated PostStatus entity, it has loaded it with the 'Published key, while the PostStatus entity on the Post was loaded with the 'PUBLISHED' key. Hence, it didn't exists in the current session, and when accessed, would cause a lazy load. Of course, at the DB level it didn't matter because it is set up to be case insensitive, but it sure made a different for comparing key equality on the CLR.

In this case, it was a simple case of entering the wrong value to the PostStatuses table that cause all this issue. As an aside, NHibernate has ways to deal with such cases in legacy databases, but that is something that I would rather fix in the data layer.

FUTURE POSTS

  1. The insidious cost of allocations - 12 hours from now
  2. Buffer allocation strategies: A possible solution - 3 days from now
  3. Buffer allocation strategies: Explaining the solution - 4 days from now
  4. Buffer allocation strategies: Bad usage patterns - 5 days from now
  5. The useless text book algorithms - 6 days from now

And 1 more posts are pending...

There are posts all the way to Sep 11, 2015

RECENT SERIES

  1. Find the bug (5):
    20 Apr 2011 - Why do I get a Null Reference Exception?
  2. Production postmortem (10):
    03 Sep 2015 - The industry at large
  3. What is new in RavenDB 3.5 (7):
    12 Aug 2015 - Monitoring support
  4. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats