The Inquisitive Coder – Davy Brion's Blog

Trying to walk that thin line between intelligence and ignorance

Archive for March, 2009

New Poll: What’s The Worst Part About Software Development As A Career?

Posted by Davy Brion on 31st March 2009

Alright, time for a new poll. Being a software developer is a pretty nice job, but it definitely has some downsides to it. Which parts do you dislike the most about this job?

  • Too many incompetent managers
  • Buzzwords
  • Dealing with incompetent devs or devs that just don’t care
  • Dealing with customers who change their mind all the time
  • Tool vendors that don’t focus on proper software development practices
  • Too much overtime
  • Corporate politics

You can select as many options as you want. Again, for the people who only reed this through their RSS reader, you can vote on my site at the top right corner. I’m not going to add more options to the poll, but feel free to mention other downsides to this career in the comments :)

Posted in About The Blog | 12 Comments »

Must Everything Be Virtual With NHibernate?

Posted by Davy Brion on 30th March 2009

If you’ve ever used NHibernate 2.0 or later, you will have undoubtedly run into the following runtime exception a couple of times:

NHibernate.InvalidProxyTypeException: The following types may not be used as proxies:
NHibernateExamples.Entities.OrderLine: method get_UnitPrice should be ‘public/protected virtual’ or ‘protected internal virtual’
NHibernateExamples.Entities.OrderLine: method set_UnitPrice should be ‘public/protected virtual’ or ‘protected internal virtual’

Oops… we forgot to make the UnitPrice property on the OrderLine entity virtual. But why does it need to be virtual in the first place? That’s a question that many people who are new to NHibernate have.

The quick answer to that question is: because we need members to be virtual in order to do our lazy loading magic/voodoo.

The longer answer is more interesting though. An important feature that any real ORM must have is transparent Lazy Loading. If you retrieve an object through an ORM, you don’t want it to automatically pull in an entire object graph (not by default anyway), yet you don’t want to litter your code with checks to see if certain associations have been loaded yet, and then loading them if necessary. This is the ORM’s responsibility. Ideally, you want to be able to access properties and have the ORM load the necessary data upon first access of those properties if the data hasn’t been retrieved yet.

NHibernate has this ability, yet it doesn’t require you to inherit from some kind of NHibernate base class or implement any interfaces or anything like that. So how does it work? Well, NHibernate uses proxies of your classes at runtime whenever lazy loading is required. Ok, so what exactly is a proxy? In this case, an NHibernate proxy is a type which is generated dynamically when NHibernate is initialized for your application (this only happens once upon application startup). A proxy type will be generated for each of your entities that hasn’t explicitly been mapped to avoid lazy loading (more on this later). A proxy type for one of your entities will actually inherit from your entity, and will then intercept each possible call you can perform on that type.

Let’s discuss a small example that might make things clearer. Suppose you have an Order class. The Order class has properties such as Employee and Customer, among others. But when you load Order instances, you might not always want the Employee property to already contain the real Employee entity instance. Same thing goes for the Customer property. By default, NHibernate considers each entity type as eligible for lazy loading unless it’s been explicitly configured not to (again, more on this later). So when NHibernate is initialized, it will know that it needs to dynamically generate proxy types for Customer and Employee. Let’s just assume these types will be named CustomerProxyType and EmployeeProxyType (they wouldn’t be called like that btw, but it doesn’t matter). Now suppose that you are retrieving an Order instance (or a bunch of them, doesn’t really matter) and you don’t instruct NHibernate to already fetch the Customer or Employee data. You haven’t requested the Customer or Employee data, so it shouldn’t be there, right? But it shouldn’t be null either, right? So NHibernate assigns an instance of the CustomerProxyType class to the Customer property, and an instance of EmployeeProxyType and initializes both proxies so that they contain their identifier value, which you already have in memory anyway after selecting the order record.

You can safely use the Order instance(s) and you can even access the Employee and Customer instances and nothing will happen. But, whenever you access any of the non-identifier members (that means properties _and_ methods) of a proxy instance, NHibernate needs to make sure that the data of either the Customer or the Employee (depending on which one you’re using) needs to be fetched from the database. So how does NHibernate do that? The proxies will override all of your properties and methods and when one of them is accessed, NHibernate will either fetch the data of the entity if it’s not present yet and then proceed with the original implementation of the property or the method, or it will immediately call the original implementation if the data was already present.

This is basic OO… your entities are base classes to NHibernate’s proxies, and those proxies need to add a little bit of behavior to your entities’ behavior. In order to do that, NHibernate needs to override every public member to make sure that this extra behavior is triggered at the appropriate time. Now, there are quite a few people who dislike this requirement. First of all, there is a minor performance cost to calling virtual members as opposed to calling non virtual members. However, this performance cost is really extremely small and in practically every situation it’s completely negligible. This extra cost certainly doesn’t even compare to some real world performance costs, like hitting the database more often than you should or retrieving more data than you really need. Another reason why some people don’t like this is because they don’t like to enable derived classes to override whatever member they want to. In some cases, this is a valid objection. In most cases however, it’s pure Intellectual Masturbation which offers no real value at all. There are other ORM’s that don’t require you to make your members virtual and they are still able to offer lazy loading features. But those ORM’s usually require you to either inherit from a specified base class, or to implement one or more interfaces that the ORM will use. In both cases, i’d argue that this pollutes your entities far more than virtual members do, but that’s just my opinion.

But for those cases where you really do not want to make members virtual, and don’t mind forgoing on the lazy-loading features of NHibernate, you can simply map those entities to not enable lazy loading at all. You could just map an entity like this:

  <class name="OrderLine" table="OrderLine" lazy="false" >

Setting the lazy attribute to false will ensure that NHibernate will not create a proxy type of your entity type, and that you will always be dealing with instances of the actual type of your entity instead of a possible proxy type. It also means that you will never be able to use any kind of lazy loading when it comes to retrieving instances of these entity types.

Posted in NHibernate | 34 Comments »

Avoiding MySQL’s MAX_JOIN_SIZE Limit With NHibernate

Posted by Davy Brion on 30th March 2009

We’re working on an application which has to use a legacy MySQL database. So far, we haven’t really had any problems with MySQL (apart from the dreadful legacy schema but that’s another issue) but today, i started getting an exception with the following message:

The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay

There is a certain complex view in our application which apparently hits this default limit set by MySQL once there is a certain amount of data present. The view itself is a costly one… it really does need to do a whole lot of joins and rewriting it to use less joins would probably take a long time.

So i figured the better option in this case would be to set the SQL_BIG_SELECTS option to 1. The only problem was: how? It’s not a setting that you can pass through the connection string (or at least, i did not find a way to do so) and NHibernate is taking care of all of the database communication.

I remembered a trick i had used earlier, which is to extend NHibernate’s DriverConnectionProvider. It could then set the setting with the appropriate value whenever the connection is opened, like this:

    public class CustomConnectionProvider : NHibernate.Connection.DriverConnectionProvider

    {

        public override IDbConnection GetConnection()

        {

            IDbConnection connection = base.GetConnection();

            EnableBigSelects(connection);

            return connection;

        }

 

        private void EnableBigSelects(IDbConnection connection)

        {

            using (var command = connection.CreateCommand())

            {

                command.CommandText = "SET SQL_BIG_SELECTS=1";

                command.ExecuteNonQuery();

            }

        }

    }

After that, you just set the DriverConnectionProvider to use in your hibernate.cfg.xml file like this:

    <property name="connection.provider">MyProject.Infrastructure.NHibernate.CustomConnectionProvider, MyProject</property>

And all is well.

Posted in NHibernate | 2 Comments »

Support Of Commercial Software vs Open Source Software

Posted by Davy Brion on 29th March 2009

I just read a post by Bobby Johnson titled: Requesting Contracted .NET OSS Bug Fixes from the Community. Bobby works for a company where he can’t easily sell the idea of using Open Source Software (OSS) in his projects to management, mainly due to the support issue. A lot of managers have this misconception that because a piece of software comes from a commercial vendor, they will receive proper support from this commercial vendor. With OSS, there usually isn’t any kind of guaranteed support. Let’s take a closer look into the commercial vs OSS support stories, shall we?

Let’s discuss support for OSS first. In the OSS world, there are no guarantees. If it works for you, great. If it doesn’t… well, this is where the problems begin. Generally, you contact the developers either through their mailinglist or their issue tracker. If you’re out of luck, you get no response. If you’re using an actively maintained OSS library (and you shouldn’t use inactive OSS projects unless you are willing to maintain it yourself in case of problems), then you will most likely receive at least some kind of response. The issue or bug might be acknowledged, or it might be dismissed.

Let’s consider the worst case scenario first. The bug or issue you reported has been dismissed. When you’re dealing with healthy OSS projects, your bug or issue will almost never be dismissed without a justified reason. If they do dismiss it, make sure you actually understand why. Usually, it’s because you’re using it wrong in some way. And yes, it actually is very possible that you are using something created by others in an manner which is incorrect. Your mistakes will either be pointed out to you, or you will find people (on the mailinglists or on people’s blogs) who have run into the same ‘issue’ and have already found a workaround.

If your bug or issue is acknowledged it usually gets fixed pretty quickly. Now, in some cases, real bugs/issues don’t get fixed immediately, usually because no good solution which won’t introduce other problems has been found yet. In this case, you’re pretty much out of luck unless someone has found a workaround. If it does get fixed, the project might release a bugfix release (not all projects do), or they will tell you that the issue has been taken care of in the trunk and that you can either use that, or wait for the next major release. If you can’t wait, you can usually still backport the fix from the trunk to the latest release.

As you can see, there are quite a few options in the OSS model. A lot of it depends on the healthiness of the piece of OSS that you’re using. In the absolute worst case scenario, you can still fix it yourself. Will it take you time (and thus, cost you money)? It almost assuredly will. But at least you have the option to fix it yourself, even if it rarely comes to that.

Let’s focus on support in the commercial software world now. First of all, i will state that the quality of support from commercial vendors can vary from poor to awesome just as well as it can vary between OSS projects. If you disagree, i would suspect that you (or your employer) either have very deep pockets, haven’t really ‘been around’, or you don’t really work in the real world. Let’s classify the commercial vendors in 2 possible categories. The first category is for dedicated software vendors. With that, i mean vendors that focus on one or a couple of things and try to do those things really well. Like, JetBrains for instance. The second category is the kind of company that tries to do everything, usually with varying results. Like Microsoft or IBM.

When products from Category 1 vendors become popular and successful over a sustained period of time, they usually have great (or at least good) support. These products usually have a big userbase, so any problems that the software may have (and we all know that every piece of software has problems) are likely to have been discovered by other users already. Often, a workaround will be available already. If not, the vendor is usually pretty quick on the ball with bugfix releases. There are obviously always exceptions to this, but i guess the same rule applies as to when selecting OSS products: consider the healthiness of the project/organization because it truly impacts everything.

And then there are the Category 2 vendors. These are the vendors that are adored by most managers. Nobody gets fired for going with IBM or Microsoft, right? These companies are huge and the odds of them disappearing over the long haul are slim to none. You paid for their products, so they will always support them. Right? I mean, they couldn’t possibly get away with shoddy service to their customers in this day and age!

Let’s get back into the real world. When you’re dealing with Category 2 vendors, the odds of getting high-quality support aren’t as high as you’d think they’d be. First of all, these vendors have a huge product portfolio of software that you can use. Some of those products will be great, and some will be horrible. I don’t think anyone can honestly state that no Category 2 vendor has ever released a product that wasn’t problematic. If you’re using one of their high quality products, then you won’t likely run into many issues. If you’re using one of their slightly less awesome products, you will likely run into issues, sometimes even a boatload of them.

So what do you do? The vendor will have some sort of means for you to communicate about the bugs or issues you have encountered. In most cases, this will be some sort of website. You can register bugs/issues and hopefully, they will be assigned to someone who will look into it. If that happens, you will hopefully get a response which states that it’s either a real issue or that the problem is on your end. Notice how this is still very similar to how it goes on the OSS world. If the problem is on your end, you can hopefully find other people who have ran into the same issue and maybe even find a workaround. If not, you are limited to figuring out a workaround for yourself. You don’t really have to option to truly fix the problem as you do have with OSS (even though that’s not always realistic either, but at least there is the possibility).

If the Category 2 vendor actually does recognize the bug/issue, there are a couple of things that can happen. They might give you a bugfix. The bugfix might be issued to you (as their customer) privately which means you’re probably paying them a boatload of money in annual license fees and support contracts. Don’t count on this kind of treatment unless you work for really big companies and even then, keep in mind that they won’t fix every real issue or bug that you might run into. If it’s a huge issue, it might be released in the short term publicly. This happens very rarely. If the issue/bug gets fixed but you don’t get a short term solution, the vendor will simply tell you “this will be fixed in vNext which will come out in 20{1-or-2-years-from-now}”.

Support is always a tricky issue, and there is no valid reason to believe that support of commercial software is inherently better than that of OSS, unless you have deep pockets. Most of us however, don’t. This post has been rather long, but it’s one of those subjects that easily gets me aggravated because i’ve suffered from crappy support from commercial vendors (particularly Category 2 vendors) just a few times too many. I’ve also had to deal with managers who’s blind faith in commercial vendors was truly astonishing a couple of times too many. Have i been burned by OSS support before? Definitely, but at least those people don’t make false promises and you do always have the option of fixing something yourself, no matter how complicated it might be.

Choosing which pieces of software to use should IMO be based on their intrinsic value, not on the company or organization that is behind it. If you can afford premium support, then great, go for it if you want. If you can’t, don’t assume that the typically provided support will be better than that of OSS projects. And no matter how great the support may be, you’re often better off choosing reliable pieces of software where you are less likely to encounter the need to seek support in the first place. If the software is reliable, then the possible support that you may require is often pretty good as well.

Choosing a piece of software based purely on the possibility of getting good support is quite simply rather short-sighted. You might just end up with a piece of software that causes you many problems, and the support you had hoped for isn’t really giving you all that much extra benefit either. Or you may end up with crappy software with great support, but wouldn’t it have been better if you could’ve avoided the crappy software in the first place? Just pick the right tool for the right job.

Posted in Opinions | 7 Comments »

Silverlight Localization Gotcha

Posted by Davy Brion on 27th March 2009

Wasted a bit of time figuring this out, so i’m posting it here for future reference. We have this multi-language silverlight app where the UI needs to be shown in either English or Dutch. So you know, i copied my TextResources.resx file (which contains the translated strings in English) and created a TextResources.nl.resx file where i replaced the English strings with the Dutch strings.

In the output folder of the Silverlight project, you can clearly see that the Our.KickAss.Silverlight.Project.resources.dll file is located in the ‘nl’ folder. The XAP file that is being copied to the actual web project however, doesn’t contain the dutch resources.

Apparantly, the key to ‘fixing’ this is opening the .csproj file of your Silverlight project, and then you need to modify the SupportedCultures element so it contains the cultures you’re supporting:

<SupportedCultures>en;nl</SupportedCultures>

There might be a way to do this from the UI within Visual Studio, but i sure didn’t find it anywhere.

And now you can simply switch between the translations setting the generated resource class’s static Culture property to the culture you want, for instance:

            TextResources.Culture = new CultureInfo("nl-BE");

Posted in Silverlight | 2 Comments »

Implementing A Value Object With NHibernate

Posted by Davy Brion on 25th March 2009

I’ve covered implementing a Value Object before, but this post is about using Value Objects with NHibernate. First, a little recap of what a Value Object is for those who don’t know yet.

A Value Object (also known as Immutable Object) is basically an object without a conceptual identity. A Value Object is defined through its inner values, and not an identity like Entities. This means that a Value Object’s inner values can not be changed after object creation, hence the term Immutable Object. Should you need to change the inner values of the Value Object, you should actually create a new Value Object.

For some of you, this might seem odd. But you’ve actually used Value Objects on many occasions already. In .NET, strings are Value Objects. So are DateTime instances. If you create a string, you can’t modify its inner value. If you do, a new string is actually created. Same thing with a DateTime. The DateTime class provides methods to add days, hours, seconds, whatever… but those methods never modify the instance’s inner value. Instead, they return a new DateTime object because each DateTime instance is immutable.

This has interesting consequences on object equality. Two Value Objects holding the same data should be considered identical objects, even though they are 2 different instances. A Value Object should therefore properly implement the Equals and GetHashCode methods.

For this example, we’ll define a Name class, which is a Value Object consisting of 2 values: FirstName and LastName. If 2 people have the same first and last name, you could say that they have the same ‘name’, right? We’ll just ignore middle names here… The combination of a FirstName and LastName would make for a good Value Object. We need to make sure that once an instance of the Name class has been created, none of its values can be modified. We also need to make sure that multiple instances of the Name class that have the same values can be safely considered equal to each other. The code of the Name class looks like this:

    public class Name : IEquatable<Name>

    {

        private readonly string firstName;

        private readonly string lastName;

 

        public Name(string firstName, string lastName)

        {

            this.firstName = firstName;

            this.lastName = lastName;

        }

 

        // the default constructor is only here for NH (private is sufficient, it doesn't need to be public)

        private Name() : this(string.Empty, string.Empty) {}

 

        public string LastName

        {

            get { return lastName; }

        }

 

        public string FirstName

        {

            get { return firstName; }

        }

 

        public bool Equals(Name other)

        {

            if (ReferenceEquals(null, other)) return false;

            if (ReferenceEquals(this, other)) return true;

            return Equals(other.firstName, firstName) && Equals(other.lastName, lastName);

        }

 

        public override bool Equals(object obj)

        {

            if (ReferenceEquals(null, obj)) return false;

            if (ReferenceEquals(this, obj)) return true;

            if (obj.GetType() != typeof(Name)) return false;

            return Equals((Name)obj);

        }

 

        public override int GetHashCode()

        {

            unchecked

            {

                return (firstName.GetHashCode() * 397) ^ lastName.GetHashCode();

            }

        }

 

        public static bool operator ==(Name left, Name right)

        {

            return Equals(left, right);

        }

 

        public static bool operator !=(Name left, Name right)

        {

            return !Equals(left, right);

        }

    }

Take a close look at the constructors. The public constructor takes both required values (firstName and lastName), and assigns them to the private fields. The default constructor (which we’ve made private) merely calls the public constructor and passes String.Empty to the public constructor’s parameters. As you can gather from the comments on the private constructor, it’s only reason for existence is because NHibernate requires classes to have a default constructor. Well actually, that’s not entirely accurate since it is possible to use classes without a default constructor but it’s not trivial do so.

Creating a private default constructor seems to be a reasonable alternative. Developers can’t create invalid Name instances (unless they cheat with reflection), and NHibernate can use the private constructor so it can create the instances before it fills the fields with the values from the database.

Note: NHibernate allows a private default constructor for Value Objects, but for Entities you will need a default public or protected constructor as private is not sufficient.

We can now use this Value Object in every entity we want by simply adding a property to the entity like this:

        public virtual Name Name { get; set; }

The mapping of the Value Object must be added to the mapping of the entity like this:

    <component name="Name" class="NHibernateExamples.Values.Name" insert="true" update="true">

      <property name="FirstName" column="FirstName" type="string" length="50" not-null="true" access="nosetter.camelcase" />

      <property name="LastName" column="LastName" type="string" length="50" not-null="true" access="nosetter.camelcase" />

    </component>

Notice the value of the access attribute. It’s set to nosetter.camelcase. That means that NHibernate will use the get property when reading the values, but it will use a camelcase private field to set the values when it’s creating the object with values from the database.

Posted in NHibernate | 12 Comments »

Entities: Required Properties And Properties That Shouldn’t Be Modified

Posted by Davy Brion on 24th March 2009

How often do you see entities mapped with getters and setters for every property, and only a default constructor (either added implicitly by the compiler or explicitly by a developer)? It’s not really the best way to map entities, so i just wanted to show a better way of doing this.

Consider the OrderLine entity. It has 4 required properties: Order, Product, UnitPrice and Quantity. It also has one optional property called DiscountPercentage. The Order and Product properties should never be changed after the OrderLine was created. It also has a database Id property which should never be changed either.

This is how the code of the OrderLine class would look like:

    public class OrderLine : IIdentifiable<int>

    {

        public OrderLine(Order order, Product product, decimal unitPrice, int quantity)

        {

            if (order == null) throw new ArgumentNullException("order");

            if (product == null) throw new ArgumentNullException("product");

 

            this.order = order;

            this.product = product;

            UnitPrice = unitPrice;

            Quantity = quantity;

        }

 

        // required for NH

        protected OrderLine() {}

 

        private int id;

 

        public virtual int Id

        {

            get { return id; }

        }

 

        private Order order;

 

        public virtual Order Order

        {

            get { return order; }

        }

 

        private Product product;

 

        public virtual Product Product

        {

            get { return product; }

        }

 

        public virtual decimal UnitPrice { get; set; }

        public virtual int Quantity { get; set; }

        public virtual double? DiscountPercentage { get; set; }

    }

There is only one public constructor, which takes all of the required properties as parameters. The protected constructor is only there because NHibernate needs it to create run-time proxies (which enable all of the lazy-loading magic). In theory, you can’t create instances of the OrderLine entity without its required data.

Also, notice how the Id, Order and Product properties only have a getter, and no setter. These values can no longer be changed by developers once the object is constructed. The UnitPrice and Quantity properties do have setters, because these values can be modified after the entity is created.

The mapping for this class looks like this:

  <class name="OrderLine" table="OrderLine" >

    <id name="Id" column="Id" type="int" access="nosetter.camelcase" >

      <generator class="identity" />

    </id>

 

    <many-to-one name="Order" column="OrderId" class="Order" not-null="true" access="nosetter.camelcase" />

    <many-to-one name="Product" column="ProductId" class="Product" not-null="true" access="nosetter.camelcase" />

    <property name="UnitPrice" column="UnitPrice" type="Decimal" not-null="true" />

    <property name="Quantity" column="Quantity" type="int" not-null="true" />

    <property name="DiscountPercentage" column="DiscountPercentage" type="double" />

  </class>

It’s pretty easy… each property that shouldn’t be changed after creation is mapped with the nosetter.camelcase access strategy. That means NHibernate uses the private field to set the value directly after creation, but will use the getters whenever it needs to read the data from the entity.

As you can see, without too much trouble you can make sure that your entities always have their required data, and that properties that shouldn’t change after creation can’t be modified either.

Posted in NHibernate | 19 Comments »

Registration For My NHibernate Talk Is Open

Posted by Davy Brion on 23rd March 2009

Ok, apparently you can now register for the Visug session where i will be talking about NHibernate.

The session is called ORMs: Entity Framework vs NHibernate, and the Entity Framework part will be covered by Kurt Claes. The location is yet to be announced but the date is September 10, 2009.

There is a maximum of 60 attendees and 20 spots are already taken so hurry up and register ;)

Posted in Off Topic | 7 Comments »

What Would You Like To See In My Upcoming NHibernate Examples?

Posted by Davy Brion on 22nd March 2009

The original version of my NHibernate Mapping Examples was pretty popular, but they were based on NHibernate 1.2 and only showed some of the basics. I have plans to create a completely new version of these examples based on NHibernate 2.1. I want the examples to be suitable for people who are entirely new to NHibernate as an easy way to learn, as well as offering value to experienced NHibernate users by showing off some more advanced features.

It would be a downloadable Visual Studio solution, consisting of 2 projects. One being the mapping files and the POCO’s, the other being a test (as in: consisting of automated tests) project which would contain the code of various usage scenarios to demonstrate various features of NHibernate.

I already have some ideas of stuff i definitely want in these examples, but i’d also like to hear from you what you would like to see in these examples. So, if there is anything you’d like to see in there, let me know :)

Obviously, i can’t promise that everything you ask for will be included but i’ll try anyway ;)

Posted in NHibernate | 9 Comments »

What I’d Like To See At Microsoft’s Technical Events

Posted by Davy Brion on 19th March 2009

As some of you may have read, i commented recently on why i wasn’t interested in going to the TechDays event. Tom Mertens, the organizer of the event, disagreed with my “questionable content, bad marketing”-statement and wanted to know what kind of content would make me want to attend these events.

First of all, i want to see more love for the Open Source Software (OSS) world within the .NET community. Like it or not, deny it if you want, but an ever increasing number of .NET developers are making use of OSS libraries/frameworks. No matter what Microsoft’s official stance on this matter is, they can’t reasonably deny that this has a positive effect on the entire .NET platform. So why is there so little attention to this portion of the .NET community? I want sessions on NServiceBus, NHibernate, Castle Windsor, StructureMap, NInject, PostSharp, Castle Monorail, etc… There’s no reason why competing Microsoft products (Entity Framework, Unity, ASP.NET MVC, Enterprise Library, …) should get a lot of attention while other (and in some cases, more mature and powerful) alternative solutions to the same problem are largely ignored.

Next up, the obsession with Drag-n-Drop Development (the other kind of DDD). I don’t care how easy some of these things can be… i care about how well these things scale. To be more specific, i want to know how well these things scale in terms of performance, code complexity, and the number of developers in a team that perform similar tasks. The typically glorified “Hello World” examples really don’t cut it. I want real world code. I want real world complexity and problems. I want solutions that are viable in the real world, i don’t care how well you can sell your Hello World solution.

I also want more focus on proper software development practices. I want more focus on readable code, testable code, reducing complexity (in real world situations), improving maintainability, enabling scalability, basically anything that enables us to produce higher quality code. When i ask people what their favorite sessions were, i almost always hear them mention sessions that deal with solving problems… either performance issues, or weird, hard to debug bugs. Pinpointing problems and fixing them are extremely important skills, but shouldn’t we all focus just a little bit more on avoiding problems in the first place?

That brings me to the speakers. I don’t want to offend anyone specifically, but i know for a fact that i wouldn’t want some of those MVP’s doing presentations to go anywhere near my code. And that statement is not based on the work they’ve put out on their blogs or in presentations or anything in public. It’s based on what they did while they were doing their job at clients. You know, real world stuff. Give me sessions by Ayende, Greg Young, Phil Haack, Scott Hanselman and others like them. And yes, i know the people i listed are either MVP’s or even Microsoft employees. I don’t care. These people genuinely care about quality instead of just their own career. That is what i want from speakers. From every single one of them.

Basically, give me an ALT.NET track. You don’t even need to call it ALT.NET… that name is a double-edged sword so i wouldn’t blame anyone for avoiding associations to it. But give me that type of content, those type of speakers. Even better, put all of that stuff in one day of the conference/event. I’d be hesitant to go for 3 days to get a good session here or there, but if there’s one day where i can spend the entire day going to the type of sessions and speakers i mentioned above, i’d be more than willing to pay out of my own pocket to go. And of all of those 1650 attendees, and despite the 95% approval rating of those who bothered to submit evaluations, how many of them could honestly say that they’d be willing to pay for the event out of their own pocket?

Posted in Opinions | 20 Comments »