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: 5,971 | Comments: 44,508

filter by tags archive

Atlas weight issueswhat am I missing?


I have the strong feeling that I am missing something. We have just run into a major slow down in one of our pages, as a result of adding the CalendarExtender. This led me to do some searching, and I am not sure that I can believe the results.

Let us take this simple page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test.aspx.cs" Inherits="ExplodingMonkeys.Web.test" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>Untitled Page</title>

</head>

<body>

    <form id="form1" runat="server">

        <asp:TextBox ID="Date" runat="server" />

    </form>

</body>

</html>

When rendered to the browser, it weight 528 bytes. Now, let us add a <asp:ScriptManager runat="server"/> to the page. The size of the page exploded to 79 kilobytes, from this change alone.

I then added the following to the page:

<ajax:CalendarExtender runat="server" TargetControlID="Date" CssClass="ClassName" Format="MMMM d, yyyy"
PopupButtonID="http://ajax.asp.net/ajaxtoolkit/Calendar/Calendar_scheduleHS.png" />

The page size reached 143 kilobytes. I am pretty sure that I am missing something here. I enabled both caching and compression in the web config:

<

scriptResourceHandler enableCompression="true" enableCaching="true" />

And then tried again. The results were better, but not really encouraging.

With just script manager: 79 KB (56 KB from cache)
With calendar extender: 143 KB (115 KB from cache)

Just to make it clear, there is a noticable delay on our pages, it went from being instantenous to taking four or five seconds. And I am talking about localhost testing, on powerful machines. (Again that HTTP 2 connections per server issue, I think).

Am I missing something, or are those the real numbers?

Enterprise Library License


The issue of the EntLib licenses just came up in the mono dev list. Quoting from the license:

Platform Limitation - The licenses granted in sections 2(A) & 2(B) extend only to the software or derivative works that you create that run on a Microsoft Windows operating system product.

That really surprised me. I supposes it makes some sort of sense for Microsoft, but I don't like it.

What would happen to NHibernate after Linq ships?


I was asked this question, and I think that the answer is interesting enough to post here.

There are two sets of technologies that MS is currently pushing.
There is Linq, which is additional support for querying directly from the language, and there is the various ORM efforts that Microsoft is pushing.
When the Linq bits will stabilize to the point where it is viable to start projects using them, there will be support for querying NHibernate with Linq.
I have looked in detailed into the four (or is it five now?) ORM efforts that microsoft is currently pushing, and I am not seeing anything that excites me there.
Early feedback that I got from Microsoft confirmed that even ADO.Net for Entities, which is the only ORM effort that tries to match NHibernate's capabilities, is not going to be extensible enough to support what I and my customers needs. This is the usual 80% solution, with a hood welded shut in all the interesting locations.
In addition to this, I find the whole configuration schema to be an order of magnitude more complex than it needs to be, with the additional complexity that this would bring later on when trying to understand what it means.

So no, I do not believe that Microsoft pushing their ORM efforts would have a bad affect on NHibernate, and having Linq would just make our life that much easier.

That said, an ORM that comes from Microsoft is probably going to be popular because it comes from Microsoft. I believe that this will merely confirm for many in the .NET world that ORM is a valid way to work.
The same people that are currently using or evaluating NHibernate will keep it, those that would never use a non Microsoft tool would use the MS ORM. Not that much different from now. People trying to migrate all but the simple projects from NHibernate to MS' ORM would run into the afore-mentioned brick walls, and would either keep using NHibernate, or would have to invest significant effort porting the application.

If Program I Can't, Programmer Am I?


Jeff Atwood has posted about the difficulities of some so-called programmers to program. The intersting facts are here. An extremely simple task is given, and quite a bit of people simply can't handle it, or take an undue amount of time to solve it.

A while ago I posted all sort of interesting questions that I would not put in interviews, it was the sort of interview questions from hell. I did a lot of interviews since then, and I have gotten sick of the level of people that I meet.

My current favoriate question is to give them this code:

public class Program
{
   public static void Main(string[] args)
  {
    //print the input string in reverse
  }
}

And ask them to solve it. It has gotten to the point that this is literally the first thing that I would ask a candidate to do. I am not picky, I would accept a solution in any imperative langauge except Ook#. And quite a bit of them simply can't do it. I am usually interviewing people that are supposed to have two years or more of experiance building applications in .Net. And they simply can't do it.

Let me tell you how vicious how I am with this horrible question, I give them a laptop (mine, actually) loaded with Visual Studio + ReSharper, full access to the net (and yes, that include Google), and they still can't do it. In one particular case, I watch the candidate go to google, skip the first result that was titled "Reversing a String in C#" and go directly to a code sample in C(!). He then spent the next five minutes shocking me by trying to get it to compile.

I can think of at least five different ways of doing it, depending on whatever you know that string can be iterated or that it has an indexer. I would expect that even if you didn't know either about string, you would realize that you can use Substring() to do it in a horribly inefficent way.

I can accept people with lack of knowledge, I can accept newbies (no prejustice is good), but I can't accept someone who can't program.

Patterns and buzzwards


Raymond Lewallen has posted Patterns are no Buzzwards, I agree with the sentiment, but I think that he is ignoring a big issue.

What is the all too frequent usage of patterns?

All too often, I am seeing patterns used indiscrimately. "What do you mean I should use a Momento here, it is in the Book". Patterns are invaluable as a way of expressing complex ideas in a simple, consistent manner, the problem is that this value is cheapened by misuse all over the place.

The idea of patterns in great, the implementation of it... could use some refactoring.

Entities, Services and what goes between them...


A developer I am working with had added a method Customer.FindOrdersByCity() and we got into a discussion why it wasn't the correct place for the method. This dicussion has made it clear that I have never really sat down and wrote what I though about what guidelines I follow with regard to good application design.

Let us start with the definations:

  • Entity - an (usually persistable) object that is part of the application model. Usually the application is based around actions on entities or by entities. Examples: Customer, Order, Employee
  • Infrastructure Service - part of the underlying infrastructure of the application, usually handles concerns that are common to many applications . Examples: DatabaseService, LoggingService
  • Application Service - part of the core application, handles business concerns that are usually specific for the application. Examples: OrdersService, CustomerService, BillingService
  • Controller - responsible for coordinating a cohesive part of the application, usually a single user interaction, but can be larger than that. Examples: NewOrderController, CustomersController
  • Views - responsible for converting the data from the controller into something that the consumer can understand. This is not just a user, I have WCF services as views, among other things.

There isn't much to talk about with regards to infrastructure services, I put them in Rhino-Commons and forget about them :-) Controllers/Views I have already talked about at length.

In general, I would like to keep my entities clean of dependencies on services. I like to put business logic only in the entities, and use the surrounding framework to get what is needed (usually this means lazy loading) without the explicit involvement of the entity with the service layer. This means that they are light-weight, independent of the infrastructure, and can be tested independantly.

Application Services are interesting, they generally use both the infrastructure services and the model to do useful stuff. They may contain business logic, if that is the best place to put it, although I would rather have it in the entities. They are usually responsible for setting things up so the entities can do their work.

As usual, the best examples are code, so let us take a look at the Order class:

public class Order

{

       public virtual Money CalculateCost()

       {

              Money cost = Money.Zero;

              foreach (OrderLine line in OrderLines)

              {

                     cost = cost.Add(line.Cost);

              }

              cost = cost.Add(this.ShippingCosts);

              return ApplyTaxes(cost);

       }

}

The business logic is in the entity, but what does the service does, then?

public class OrderService

{

       public virtual Money CalculateCostForOrder(int orderId)

       {

              Order order = Repository<Order>.FindOne(

                     (Where.Order.Id == orderId).ToDetachedCriteria()

                           .SetFetchMode("OrderLines", FetchMode.Eager));

              return order.CalculateCost();

                           

       }

}

This is a very rough draft, but you get the idea, I hope. The service loads the entity, making sure to load the OrderLines collection with the entity (to save another query later) and delegate the calculation to the entity.

What did I gain here? I could have just put the calculation directly in the service, couldn't I?  I could do that, but then I would have lost the OO capabilities that I have with entities (vs. Data Transfer Objects). If I wanted to have a OnSaleOrder, with a special discount, I could do this polymorphically, instead of adding conditions to the service.

There is a strong relation between a service and an entity (but hopefully not the other way around), this means that there usually will be a service per entity, but that is not always the case (OrdersService and NewOrderService, for instance) and there certainly will be cases where there are entities that have no service (those will usually not be the aggerate roots of the system, of course).

The service in general has a very procedural interface, although I am starting to consider fluent interfaces and method objects for services as well.

Unit Testing Database: Embedded vs. In Memory..


A while ago I extolled the benefits of using an in-memory database for tests. Now, the only in memory database that I know of (that has a ADO.Net provider) is SQLite. SQLite is a great database, except for one tiny issue. It is has a really weak support for dates, requiring your to jump through multiply hops to do anything even slightly interesting with dates.

Since I am mostly working on business applications, strong support for dates is a crucial issue for me. With great relucance, I moved my tests to use SqlCE embedded database. This is still an order of magnitude faster than going to a remote server, but it was much slower than running the whole test in memory, never touching the disk.

The speed difference became acute when I tried to run many Unit Tests (vs. Integration Tests) using the embedded DB, it was far too slow to be a real unit test framework.

For this reason, I now have two ways of using database from unit tests, using In Memory for most tests, and using Embedded DB when dates are important. You can check the code here.

Anyone can recommend a .NET accessible in memory database with good dates handling?

Rhino Mocks 3.0: Beta 2 Released


Took a bit longer than I anticipated, since people found some really hard bugs with regards to the generics support. I now know a lot more than I ever wanted to about generics, and I considered myself an expert before-hand.

Anyway, the new bits have:

  • Improved support for wacky generics scenarios. Thanks to James and Thierry.
  • Better support for types having non inheritable attributes that cannot be easily replicated. Thanks to Aaron.
  • Better support for types implementing interfaces by using a base class that is located in another assembly.* Thanks to Aaron.
  • Included XML Documentation files.
  • All merged assemblies are not marked internal, to save your from collisions if you are using the Castle bits yourself.

Changes:

The CallOriginalMethod() was deprecated, you are now encouraged to use CallOriginalMethod(OriginalMethodOptions.NoExpectation) or CallOriginalMethod(OriginalMethodOptions.CreateExpectation) instead. The reasoning behind the change is that currently CallOriginalMethod looks like it create an expectation, but it doesn't really does it, s it is better to be explicit about the whole thing. Thanks for Enrst for pointing it out to me.

As usual, the binaries and source are here.

* If you understood what that meant...

FUTURE POSTS

  1. Paying the rent online - about one day from now

There are posts all the way to Aug 03, 2015

RECENT SERIES

  1. Production postmortem (5):
    29 Jul 2015 - The evil licensing code
  2. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
  3. API Design (7):
    20 Jul 2015 - We’ll let the users sort it out
  4. What is new in RavenDB 3.5 (3):
    15 Jul 2015 - Exploring data in the dark
  5. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats