Ayende @ Rahien

Refunds available at head office

NHibernate Query Analyzer for NHibernate 1.2 GA

I am a bit late with this one, but here is a new version for NHibernate 1.2 GA. This also supports Castle Active Record, hopefully in a version neutral way.

You can get it here, or admire the UI here:

image

As an aside, I am thinking about adding Criteria Query functionality, since this is something that I use a lot. I am not sure yet what form this would take, at any rate it would involve runtime code generation, so that is complex (and sort of fun/pain).

I am opened to ideas.

Have fun...

Arrest that man! He had built workaround a technical limitaion!

Alex* has posted a piece of code that will solve my issue with Window Live Writer and spell checking.

The problem is that this is clearly working around a technical limitation in the software, as a non English speaker, I am obviously required to use Windows Live Writer Team Edition, which will (in the next version only, mind you) support English spell checking for non-English speakers. I am expecting the Cease & Desist to come at any moment, and Alex is currently expecting an attack from the Tean Ninja Lawyers teams.

Nice hack Alex, now off to prison with you.

* Sorry to pick on you, but that was too good an example not to use.

Castle.MonoRail.ViewComponents

So I finally found the time to build the project and put it on castle contrib. The main idea is that this is the place where community contributed view components can be aggregated, including documentation and sample code.

You can get the initial stub here, it includes the Grid Component and Smart Grid Component, as well as (hopefully) thorough documentation about their usage.

Thou Shall Not Work Around Technical Limitations

Frans Bouma has a really good overview of the implications of Microsoft behavior in the TDD case. The thing that really bothers me is that the thing that they are hinging their treats against Jaime is "work around techincal limitations".

Well, excuse me, but that is my job. What am I supposed to in cases such as this or this? Report a bug to Microsoft and wait two years so maybe they will fix it? (Or maybe they will decide that it is there for backward compatability.

This is generating so much bad will around the community, I just can't understand Microsoft's position in this matter. I am with Frans on this issue, I don't think that Jaime is in the wrong here, neither technically nor legally.

We have heard from a few Microsoft people about the issue, mostly re-iterating the same nonesense. I would like to get a response Scott Guthrie on this subject.

ReSharper 3.0 Beta

I am using R# 3.0 Beta, and I am loving it, check out the suggestions:

image

 

And this one:

image

Or this one:

image

 

The really great thing about it is that it is three key strokes from suggestions to having better code!

Effective Software Development or Policing Of Monkeys

Jeff Atwood is talking about why background compilation is part of a culture of code monkeys and that we should accept it and get on with the program:

You could throw emacs and volumes 1-5 of The Art of Programming at your development team. Or you can buy them the best, most advanced development tools on the market. Which approach do you think will be more effective?

One of the problems with the army of monkeys approach that everyone seems to ignore is that treating someone like a monkey will get you monkey-like responses. We have a problem of escelating complexity in software, and trying to solve it by serregating the problems to the "Smart Dudes" and the "Monkeys" is not really helping. We are not writing Hello World applications any more.

I had the chance to try to port a monkey's code from one langauge to the other, and I couldn't make sense of it. You can imagine at what stage I had to throw up my hands and seek that monkey out to have it explain to me what the hell is going on in the code. It was 2 months old code, and the monkey couldn't do it. The magic numbers in the code were what the monkey was told to write, the logic constructs in the code were what the monkey was told to write. The bugs were the monkey's own fault, I assume, but it may very well be the case that the monkey was instructed to put them in as well.

Trying to get a good product out of an army of monkeys requires constant policing, lest they do something stupid. Software is such a complex beast that have a monkey anywhere in the process will put a serious risk to the project at large. Some of the stuff that I have seen:

  • Using a public static bool g_IsUserAuthenticated;
  • Subscribing each page to a global & static event handler.
  • String concentration for query building (using the safeForSQL() method, of course)
  • The single user only web applications
  • For more references, check the Daily WTF

Each of those share a single trait, this is a single stupid thing that had a drastic affect on the entire application.

In the case of the static event handler, it took about two days to see the effects properly, at which point the application crushed with OOM errors. That was fun to find out.

Armies of monkeys simply doesn't scale, a monkey can't handle complexity well, so you end up dumbing the environment to the level of the monkey, therefor, you are reducing your ability to make any sort of change and maintainability is a nightmare.

So, Jeff, I do agree with you that there is this cult of monkeys, I do not agree that we should agree to this.

Blog Design Help

I have been using the blog skin for the last two years or so, and I really like the look & fell of the blog. There is a problem, however, with some of my posts on 1024x768. I got several complaints about it, but all the "easy" solutions that I have tried are not really working well.

So, I decided to ask your help :-)

You can get the blog skin here: http://www.ayende.com/Files/BlogSkin.zip It is a standard SubText skin, and I only want one thing, to get it to work reliabely on 1024x768.

Thanks in advance...

Developers are consenting adults, treat them as such

I was just asked how I prevent a developer from doing something stupid. My answer was "rational explanation". I see way too much effort to protect developers from themselves. There is a very simple approach to handling rogue developers, it involve a conversation with their manager and a guided tour toward the door.

That is not to say that you shouldn't have reasonable error messages, "token error 0x443234FEA" is pretty nasty to do, but don't try to make them work without all the power that they can have.

Published at

Something is very wrong in Vista

I just tried to copy some files out of FTP using Vista. I said that it would take ~15 minutes. Since it was ~30 files whose total weight was about 30Kb, I was concerned. I was able to connect to my FTP and download them using the command line in about 5 minutes, leaving me ample time to kill the annoyingly long copy operation.

What the hell is it doing that it is taking so long to do something so simple?

At what point do you say WTF?! Runtime addition of methods to class in C#

Assume that I have this piece of code: 
public interface InterfaceWithExplicitImpl<T>
{
   IEnumerator<T> GetEnum1();
}
Now, check the picture. This is 100% repreducable, but only under very specific set of scenarios (basically, running System.Reflection.Emit stuff). I am not sure how exactly I am supposed to handle this sort of an issue.
 
WTF
 
Here is the code to repreduce the issue:
You need to reference Dynamic Proxy 2, but this code produce stuff that I would bet is flat out impossible.
 
   1:   class Program
   2:   {
   3:       static void Main(string[] args)
   4:       {
   5:           Console.WriteLine("Before it has {0} methods", typeof(MyInterfaceWithExplicitImpl<int>).GetMethods().Length);
   6:           
   7:           ProxyGenerator generator = new ProxyGenerator(new PersistentProxyBuilder());
   8:           generator.CreateInterfaceProxyWithoutTarget(typeof(MyInterfaceWithExplicitImpl<int>), new StandardInterceptor());
   9:           generator = new ProxyGenerator(new PersistentProxyBuilder());
  10:           generator.CreateInterfaceProxyWithoutTarget(typeof(MyGenericInterface<object>),
  11:                                                           new Type[] { typeof(MyInterfaceWithExplicitImpl<int>) },
  12:                                                           new StandardInterceptor());
  13:   
  14:   
  15:           Console.WriteLine("After it has {0} methods", typeof(MyInterfaceWithExplicitImpl<int>).GetMethods().Length);
  16:       }
  17:   }
  18:   
  19:   public interface MyInterfaceWithExplicitImpl<T>
  20:   {
  21:       IEnumerator<T> GetEnum1();
  22:   }
  23:   
  24:   public interface MyGenericInterface<T> where T : new()
  25:   {
  26:       T DoSomething(T t);
  27:   }

"select" Isn't Broken

At one point in class, I talk about maintainability, and I happened to mention renaming a column in the database.

One of the students got up and started what I can only call a rant on how people that renames columns in the database should be shot in the head and then thrown into the garbage heap. Appernatly proper burial was too good for those monsters that renames columns in the database. I am sure that the story behind this reaction was interesting, and probably funny if you aren't in it.

What interested me that this was such a powerful reaction to a problem that I don't even have. I have run into several of those recently, and I must say that some people has fairly creative solutions to problems that I don't even have.

One company has decide to forbid the use of identity columns all together, and forces all PK generation to be done through counters tables. Again, I don't have the story, but I have a strong feeling that @@IDENTITY is behind it.

At DevTeach I was shown a clever way to work around dependency management on the naked CLR, I was impressed by the inventiveness, but it was an approach that could only be taken so far.

The point of this post is to urge you to take several steps back when you run into something that doesn't makes sense, and try to find a way that does make sense, if you have to do something that you feel the underlying framework/services should do, you are either doing something wrong, or the platform is wrong. In general, it is safer to assume that you are doing something wrong and that there is a better way. Find out!

Localization: All the way or don't bother

This is from trying to install Acrobar Reader on my system, which has Hebrew langauge installed.

image

Either you are going to verify that you have correctly localized your stuff, or offer them in English. This half measure is worse than either approach.

The Complexity Suppression Disorder

So, applying the separation of concerns principal to blog posts again, I wanted to talk about another aspect that had me thinking as a result of teaching .Net. I literally had no idea how complex development was until I had to stand in class and explain the tradeoffs for the various approaches for implementing things. Several things that kept popping up are:

  • Concurrency
  • Multi thread safety (in the abstract, at least) - That one is easy, don't do multi threading. Failing that, don't do multi threading on shared state. Failing that, welcome to the fun world of multi threaded debugging :-)
  • Normalization
  • Ease of use (API wise)
  • Information hiding
  • Exception non-handling *(not a typo)

Those are cross cutting concerns that affect a lot of the actions in the application. When I develop, I don't think that I am really aware for this, I just write code according to the best practices that I pub-sub to, and it usually end up being correct.

Having to implement a solution in front of a class, it is much more difficult, because now I have to articulate these best practices, why they are important and their reasoning. This made me realize how often I do the same without really bothering to go through the entire check list.  Did you know that Rhino Mocks has a mode that is actually safe for multi threading, for instance?

Now I need to re-learn how to forget about all those messy concerns and just build the application the way it is supposed to be, without starting to worry about all of those concerns until I really need to.

Nevertheless, it is pretty amazing that I can spend 30 minutes talking about 15 lines of code, pointing out all the various concerns that it needs to handle, and how it does them. It is amzing and depressing in the same time, we need to handle so much stuff that this is getting ridiculous.

Tags:

Published at

Knowing by reading, Learning by doing, grokking by teaching

I am currently teaching an MCPD course for about 20 people, with various programming backgrounds but little to no .Net experience. It is an interesting experience, and I realy like teaching (I get to speak for several hours and they have to listen to me :-) ). Plus, it is a good way to get a close up visual of how the new developers think.

I firmly believe that the only way you can really understand a topic is by having to teach it to someone. You can know something by reading about it, and you may even be able to recall it when you need, and you learn by doing something, but you are only assimilate this stuff when you teach it to someone, because then you have some sort of a coherent mental model in place.

Case in point, transaction isolation levels, I know this stuff, I have certainly used it in many places, I just don't think that I was ever able to really grok that before I had explained it to a class of people. This required not just explaining how it works, but the why, when and where. At the end, I came up much smarter, and I was the teacher :-)

The guys (and gals, but Hebrew is a sexist language, so I am just going to use guys from now on) in the class has various experiences, from assembly programming (and what fun it is to explain OOP to an assembly programmer), through C++ guys, to classic ASP programmers, to .Net programmers that want to know it better. That is an interesting (and challanging) mix.

There is the official curriculum for this course, and I am sort of horrifyingly following that. (At one point, I had to stop the class and do a code review of the example solution, it was very... instructive as a worst practice example.) I have a problem in teaching people stuff that I am not actually using, I feel like I am speaking in two voices here.

Nevertheless, I literally can't teach them the stuff that I use. Not because of the limitations of the course, but simply because to do that would be actively harmful to them. You can't (and shouldn't) try to grasp OR/M before you have a good understanding of SQL and how ADO.NET works. I can figure out how trying to teach IoC would go: "Oren said that we shouldn't use new Xyz()"

It would be harmful because they first need a good foundation, and only then we can build on top of that. I do insist on Single Responsability from the get go, though :-)

Adaptive Fetching Strategies in ORMs

Aaron has a post about some wild ideas about OR/M fetching, specifically, auto-learning fetching strategies. The idea has merit, and the required technicalities are already inside NHibernate, I can imagine a proxy that talks to to fetching strategy to inform it about accessed properties, which would give it the information needed for the next time the same query is made.

But, how do you correlate queries?

I have "Repository<Salary>.FindAll(Where.Salary.Employee == CurrentEmployee);" in several places, in the "list employee salaries page" and in the "calculate tax" service. Each requires a different fetching strategy. Worse, I have this hiding in a method call GetEmployeeSalaries(Employee), so now we can't even use the callsite information to do our smarts.

We can try to do something with stack traces, but I am not sure that this is something that you would really want to do, as this has performance implications of its own.