Ayende @ Rahien

Refunds available at head office

Frustration

[via Alex] The says that a picture is worth a thousands words, I have never found a picture that better express what frustration is:

(Image from clipboard).png

Real Quotes from a Status Meeting

Yes, they actually were said in a meeting yesterday:

  • This is a feature, not a bug.
  • Not supported
  • The spec is flawed.

No, it wasn't me saying them, and they actually made sense in context (but were hilarious none the less).

Tags:

Published at

Magic numbers...

Somehow it crept by me without notice, take a look at my blogging stats:

(Image from clipboard).png

Over a thousands posts just this year, damn!

Tags:

Published at

The value of software

The author argues that in software, you should either get the cheapest tool you can find or the most expensive one, go read this, I definately agrees.

Highly interconnected graphs & Business Logic

Imagine the following model:

Now, the feature that you need to develop is "suggest employees for open position", which requires:

  • Finding all the employees whose contract allows this position.
  • Where there isn't any rule that prevent it (and rules can be on a contract, employee details, employee or group of employees),
  • That the employee is not in a similar position right now.
  • That the employee didn't ever fill a higher level position.
  • Preferred: That the position is in a location that the employee is in.

What I would like to know is how would you solve this issue... (not just using NHibernate, using any tool of your choice, with the limitations that rules cannot be evaluated as SQL, they are .Net objects that interact with other .Net objects).

Published at

About that internal again...

In an email exchange today:

About internal, I understand your PoV, however, you may be writing your business layer & domain model for other developers. If they are unexperienced, you may find it important to hide some stuff...

I just had a discussion about it yetserday with a team mate.
He talked about signing off things with me before starting to implement them, my response was along the line of...

I am no longer in the army, and that I refuse to work this way. I get too little code at the moment as it is. If I don't trust you to do the tasks that I give you, why am I giving them to you? Either you don't know, and then we will pair and do them together, so you'll learn what you need to do similar tasks next time, or you do know, in which case I have no business standing over your shoulder.

Now, granted, I will try to go over the code and see if there are any things that I am not comfortable with. And at first, there were a lot of things that I wasn't comfortable with. I try to ignore coding styles because they usually don't matter much to me, but naming, abstraction, and complexity are things that I am very sensitive to. After the forth or fifth time that this is happening, I find that they understand what I consider a red flag.

And yes, this means that I can sit with a dev for a few minutes, talk about what needs to be done and maybe explore the object model that is required. Then the dev is on their own, if they have issues, they ask.

I was a police officer, I didn't like it then, and I don't intend to start policing people again (although being able to revoke people's license to code for reckless developing would be an interesting concept).

 

Great Interview Task

A couple of days ago I had a really great interview, I figure that I am due one after the long series of horrible candidates that I had recently. Anyway, I did a couple things there that I think that I will carry on to the future interviews. I gave the guy a laptop, and the following excersise, given the follwoing object model:

public class Customer
{
  public List<Order> Orders = new List<Order>();
  public string CompanyName;
  public string Id;
}
public class Order
{
  public int Id;
  public Customer Customer;
  DateTime ShippedAt;
  DateTime OrderedAt;
}

And the following SQL Statement:

SELECT  Customers.CustomerID,

        Customers.CompanyName,

        Orders.OrderId,

        Orders.OrderDate,

        Orders.ShippedDate

FROM    Customers

INNER JOIN Orders ON Orders.CustomerID = Customers.CustomerID

The task is to give me a list of Customers with their orders collection filled. No duplicate customers are allowed. I think that you can see why this is a subject that is near & dear to my heart ;-) Anyway, this is a task that test several distinct parts of the candidate's knowledge, SQL/Database, ADO.Net, minor data structure, logic, etc. It also says a lot about the background of the candidated as they approach it.

Another thing that I thing that I'll keep is asking them what they don't know and then give a task in that area. The task is neccecarily trivial, but it shows how the candidate can learn and think. I don't want co-workers that needs step-by-step instructions.

Tags:

Published at

Fix for "Cannot find custom tool 'NHibernateQueryGenerator' on this system."

If you have downloaded NQHG 1.7 and are trying to use it from Visual studio, you probably got the following error:

Cannot find custom tool 'NHibernateQueryGenerator' on this system. The issue is that I didn't update the setup script correctly, and the version that it registers as a COM addin is set to 1.6, while the assembly version is 1.7. This cause the COM load to fail.

This script will reset the NHQG version to the correct one, until I manages to find some time for fixing this properly.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\CLSID\{DE8A7135-96F6-47BA-9DC9-D7D837B4CDE3}]
@="NHibernate.Query.Generator.NHibernateQueryGenerator"

[HKEY_CLASSES_ROOT\CLSID\{DE8A7135-96F6-47BA-9DC9-D7D837B4CDE3}\Implemented Categories]

[HKEY_CLASSES_ROOT\CLSID\{DE8A7135-96F6-47BA-9DC9-D7D837B4CDE3}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]

[HKEY_CLASSES_ROOT\CLSID\{DE8A7135-96F6-47BA-9DC9-D7D837B4CDE3}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="NHibernate.Query.Generator.NHibernateQueryGenerator"
"RuntimeVersion"="v2.0.50727"
"CodeBase"="C:\\Program Files\\Rhino\\NHibernate Query Generator\\NHQG.exe"
"Assembly"="NHQG, Version=1.7.0.0, Culture=neutral, PublicKeyToken=0b3305902db7183f"

[HKEY_CLASSES_ROOT\CLSID\{DE8A7135-96F6-47BA-9DC9-D7D837B4CDE3}\InprocServer32\1.7.0.0]
"Class"="NHibernate.Query.Generator.NHibernateQueryGenerator"
"CodeBase"="C:\\Program Files\\Rhino\\NHibernate Query Generator\\NHQG.exe"
"RuntimeVersion"="v2.0.50727"
"Assembly"="NHQG, Version=1.7.0.0, Culture=neutral, PublicKeyToken=0b3305902db7183f"

[HKEY_CLASSES_ROOT\CLSID\{DE8A7135-96F6-47BA-9DC9-D7D837B4CDE3}\ProgId]
@="NHibernate.Query.Generator.NHibernateQueryGenerator"

Geek Humor;

From the IRC channel;

1> i already work 12-15 hours a day
2> well stop that!
1> i'm working on that...
1> which, of course, is infinite recursion

This is hilarious!

Tags:

Published at

MonoRail Applications: Testability Expectations

Scott's has suggested that I post about the different approaches to testability in MonoRail vs. other MVC implementations. Specifically, this was caused by Scott's post about MonoRail, and a concern he raised about MonoRail and testability:

I haven't seen much Model-View-Presenter framework stuff in MonoRail, but I might have missed it.  I'd prefer to not have to loose the testability that comes with the pattern

At first, I really couldn't see how he got to this conclution, but after a short email discussion, I think that I can see how he got this idea. And this is likely to confuse other people who looks into MonoRail. The confusing issue here is that many people has gotten use to a an active view approach. Let us take the following example and see how we should build it using classic ASP.Net MVC and using MonoRail.

You have form with a text box and a button. When the button is pressed the textbox and button are hidden and the text "Hello "+ whateverInTheTextBox appears.

Can't get any simpler than that, now can it?

Using ASP.Net MVC, you would probably have something like this view;

public class HelloUserView : Page, IHelloUserView
{
  IHelloUserController controller;
  public HelloUserView ()
  {
     controller = new HelloUserController(this);
  } 
  protected void Button_Click(object sender, EventArgs e0
  {
    controller.ButtonPressed();
  }
  // more stuff
}

And this controller:

public class HelloUserController : IHelloUserController
{
  IHelloUserView view;
  public HelloUserController (IHelloUserView view)
  {
    this.view = view;
  }
  public void ButtonPressed()
  {
    view.HideTextBoxAndButton();
    view.DisplayText("Hello, "+ view.TextFromUser);
  }
}

Testing this is fairly simple, you mock the view and assert that the correct calls are made.

MockRepository mocks = new MockRepository ();
IHelloUserView view = mocks.CreateView<IHelloUserView>();

//set expectations
Expect.Call(view.TextFromUser0.Return("ayende");
view.HideTextBoxAndButton();
view.DislayText("Hello, ayende");
mocks.ReplayAll();

HelloUserController controllerUnderTest = new HelloUserController(view);
controllerUnderTest.ButtonPressed();

mocks.VerifyAll();

This is how most of the MVC implementation are working, the view is active in that it takes part in the process (even if only by exposing events).

Now, let us try this again, using MonoRail, here it the initial view:

<form action="/helloUser/displayGreeting.rails">

  Your name: <input type="text" name="userName">

</form>

And the controller is:

public class HelloUserController : Controller
{
  public void Index() { } // just display the view

  public void DisplayGreeting(string userName)
  {
    PropertyBag["userName"] = userName;
  }
}

And the DisplayGreeting view is:

Hello, ${userName}

What just happened? The views in MR are strictly output mechanism alone. Unlike Win/WebForms, where the view needs to inform its controller about the various events.The framework is responsible for handing stuff to the controller. Actually, thinking about it, is is not quite right. The view is responsible for setting things up so a user action will cause the appropriate things in the controller. This is a somewhat more passive role, but it seems to me that it is still doing its job.

When it comes to testing the controller, there isn't a need to mock the view, you can directly verify that the controller is creating the appropriate entries in the PropertyBag/Flash, which the view will use. When it comes to the test the interaction between the view and the user, it is important to note that the view doesn't do such a thing at all. As you can see, there isn't a responsability here that isn't being tested, the view just doesn't play this part.

In the above example, we are relying on the framework to handle a lot of things that we had to deal with ourselves previously. Here is how we can test the functionality:

HelloUserController controllerUnderTest = new HelloUserController ();
controllerUnderTest.DisplayGreeting("ayende");
Assert.AreEquals("ayende", controllerUnderTest.PropertyBag["userName"]);

The view have setup the output so the action of the user would cause the response on the controller. It is a quite different paradigm when you look at it from a conceptual level, but very simple to grasp when you just look at what is going on.

Note To Google: Outsourcing Support to Mail Daemon - Not Good Idea

So, I have trouble with my adsense account, I am doing the right thing by hitting the support pages and actually reading them, but they aren't helping my issue. Therefor, I decide to contact Google's support. I use their own support page, and send an email.

(Image from clipboard).png

I was surprised to get a response almost immediately, the problem is that I wasn't pleased with their message...

(Image from clipboard).png

WTF?!?!?!

Tags:

Published at

OSS & Duplication of effort

David Hayden responded to my and Jeremy Miller posts about OSS in Microsoft world. He raised the following issue:

One of the things that I have noticed in the Microsoft OSS Community ( and this may not be unique to this community ) is the duplication of effort. This duplication of effort is no doubt slowing the overall progress of all projects, but it also makes it dang confusing and sometimes utterly impossible to know what niche a project fulfills, the amount of community support around it, how it overlaps and differentiates itself with similar projects, etc.

He lists several competing OSS projects:

  • NUnit or MBUnit?
  • StructureMap, Spring.NET, or Windsor?
  • NHibernate, Gentle, IBatis, Retina?
  • dasBlog or SubText?
  • log4net or NLog?

I don't see an issue here. The OSS community isn't a well coordinated place by defination. Each of the above solve its developers problems best, as a user of those projects, all you need is to decide what you want to do with those.

Take NUnit vs MbUnit, MbUnit has a lot more extentions, [RowTest] is a good example. NUnit was there first, and it have excellent tool support.

In the IoC world, Spring.NET is for those who doesn't have enough XML in their life :-) and want to control every bit & piece of the system explicitly. Windsor take a whole different tack and StructureMap was there first (sorry, never looked at it closely enough to say what its advantages are).

If you want to write your own SQL, and have the OR/M map from the data reader to objects and vice versa, iBatis is probably the thing for you. If you want to give up SQL entirely, NHibernate will fit the bill much better.

dasBlog is a blog engine that doesn't require a database backend, which was quite important to me when I first built this blog. SubText has a database backend, and it means that people can do all sorts of nifty things with it that are harder with dasBlog.

log4net vs NLog, I think you can see the pattern.... (and I never used NLog, so can't comment, except that the config looks simpler).

They are advantages to doing things twice, in different ways, for one thing, you get several solutions that you can choose from. The other interesting thing is that because they are OSS projects, it is not a walled garden where one project has built a feature that isn't in any of the other projcets, and they compete on that.  Take dasBlog and SubText as a good public example, they are borrowing each other code fairly often. This is a very good thing, in my opinion.

There isn't an issue with having competing projects, quite the contrary, having several projects on the same subject, often solving similiar problems in wildly different ways, gives the community at large a whole lot more to choose from. This wish for a single project per subject, one to rule them all, is not healthy in the long term, as I see it. I don't lose anything from having another OR/M framework on .Net, even though I am a heavy contributer/user for NHibernate, for instnace.

This is not a sum zero game.
Tags:

Published at

Interview Questions From Hell: Take IV

It somehow came up in chat today, and it occurs to me that this is yet another great question that I probably will never ask in an interview:

Tell me how System.Object.GetHashCode() works, here is a computer with net connection, google away.

Personally, it took me 11 minutes to find how the implementation worked, and another seven to find it.

Possible reactions:

  • Candidate faints -> Good timing, would've waste my time staying up and talking
  • Cadidate explains that he doesn't care about such things -> and if he can convince me that he doesn't care for the right reasons, excellent.
  • Canidate hazzard a guess that is not even remotedly close to the truth, like serializing the object to binary and hashing that -> interesting approach, remind me to send a perf team to your next employer :-)
  • Candidate explains that they don't know, but give a reasonable alternative for it -> nice
  • Candidate goes and find the implementation -> good, now explain it to me :-)
  • Candidate gives the answer of the top of their head -> dude, if you weren't on the BCL team, you are wierd

Hm, I wasn't on the BCL team, so this make me wierd... Maybe I should rethink this approach

 

Tags:

Published at

NHibernate Web Cast Series: Thinking about the infrastructure

Here is a status report about the NHibernate Course that I talked about previously. I have talked with Justin, and at the moment is looks like we are going to do a web cast series about NHibernate. The draft syllabus can be found here, although this is merely a list of topics that we would like to cover.

We are thinking of roughly 30 hours(!) or so of web casts, which should be enough to cover NHibernate from end to end, and maybe leave me out of a job :-). A you can imagine, trying to do something like this is a fairly lengthy, and involve quite an invensement in both time and effort. In other words, we would like to get paid for this effort.

Now, beyond producing the web casts, I don't really want to deal with the hassle of creating a a site to sell the web casts. This is more of a headache avoidance issue than anything else. We checked in a couple of places, and it doesn't look like anyone we know is willing to handle the hosting/billing/headache issues. What I would like to know is whatever you can recommend (to me, or me to them) a way to handle this.

If all else fails, we would handle this ourselves, but I would much rather worry about technical purity than about encrypting payments and calculating taxes. We are open to suggestions, so you can either drop me a line here, or contact me directly via my email address.

Building Reusable UI Components In MonoRail

I have talked recently about the problems with 3rd party controls and I made the statement that most of the time, I would want to do this on my own, since figuring out how to get to where I want with a 3rd party control often takes as much time as developing the functionality myself. Scott Bellware commented on this post, asking how to get this functionality in MonoRail.

Here is a simple implementation of a grid ViewComponent in MonoRail. It supports header / footer (which the GridView doesn't), empty template, alternating rows schemes, and pagination. I feel that this encompass quite a large precentage of the feature that are in the ASP.Net GridView, so let us see how we build it. We start by deriving from ViewComponent:

public class BasicGridComponent : ViewComponent

We then define the sections that we support. If you are coming from Web Forms world, you can think of View Components as Server / User Controls and sections as the equipollent of ITemplate.

static readonly string[] sections = new string[]

    {

        "header", "footer",

        "pagination", "empty",

        "item", "alternateItem",

        "tablestart", "tableend"

    };

 

public override bool SupportsSection(string name)

{

    return Array.IndexOf(sections, name) != -1;

}

Now, let us build the all important Render() method:

public override void Render()

{

    IPaginatedPage source = (IPaginatedPage) ComponentParams["source"];

 

    ShowStartTable();

    ShowHeader(source);

   

    if(source != null && source.TotalItems>0)

    {

        ShowRows(source);

    }

    else

    {

        ShowEmpty();

    }

 

    ShowFooter();

    ShowEndTable();

    ShowPagination(source);

}

One interesting thing to note here is that we are using IPaginatedPage as our data source, which provides us with most of the paging support out of the box. We are mostly delegating to methods that does a single thing, mostly, they provide default overridable functionality. Here is a sample of such a method:

private void ShowEmpty()

{

    if(Context.HasSection("empty"))

    {

        Context.RenderSection("empty");

    }

    else

    {

        RenderText("Grid has not data");

    }

}

Most of the other methods are implemented in a similar fashion, we provide a default implementation and we can override it in place by specifying the appropriate section. ShowStartTable, ShowHeader, ShowEmpty and ShowFooter all share the same concepts. ShowPagination share the same idea, but is a bit more complex, because it outputs the entire pagination toolbar, which has a lot of conditionals.

ShowRows, however, is very interesting:

protected virtual void ShowRows(IPaginatedPage source)

{

    bool hasAlternate = Context.HasSection("alternateItem");

    bool isAlternate = false;

    foreach(object item in source)

    {

        PropertyBag["item"] = item;

 

        if (hasAlternate && isAlternate)

            Context.RenderSection("alternateItem");

        else

            Context.RenderSection("item");

 

        isAlternate = !isAlternate;

    }

}

We check if we have an alternateItem section, and render the sections accordingly. The PropertyBag["item"] allows the section to access the current item in a convient fashion.

Here is the code for this View Component:

<?brail

component BasicGridComponent, {"source": contacts}:

  section header:

?>

    <th>EMail</th>

    <th>Phone</th>

<?brail

  end

  section item:

?>

<tr style="background-color: #fea;">

  <td>${item.Email}</td>

  <td>${item.Phone}</td>

</tr>

<?brail

  end

  section alternateItem:

?>

<tr style="background-color: white;">

  <td>${item.Email}</td>

  <td>${item.Phone}</td>

</tr>

<?brail

  end

end

?>

But, you know what, this is too much for me to write. Let us say that I love the AutoGenerateColumns option in the GridView. What would it take to implement it as a ViewComponent? Well, as it turns out, not much, really.

public class GridComponentWithAutoGenerateColumns : BasicGridComponent

{

    private PropertyInfo[] properties;

 

    protected override void ShowRows(IPaginatedPage source)

    {

        if (properties == null)//there are no rows, if this is the case

            return;

        bool isAlternate = false;

        foreach(object item in source)

        {

            RenderText("<tr>");

            foreach(PropertyInfo info in properties)

            {

                if(isAlternate)

                    RenderText("<td class='alternateItem'>");

                else

                    RenderText("<td class='item'>");

                RenderText(info.GetValue(item,null).ToString());

                RenderText("</td>");

                isAlternate = !isAlternate;

            }

            RenderText("</tr>");

        }

    }

 

    protected override void ShowHeader(IPaginatedPage source)

    {

        if(source!=null && source.TotalItems>0)

        {

            IEnumerator enumerator = source.GetEnumerator();

            enumerator.MoveNext();

            object first = enumerator.Current;

            properties = first.GetType().GetProperties();

            foreach(PropertyInfo property in this.properties)

            {

                RenderText("<th>");

                RenderText(property.Name);

                RenderText("</th>");

            }

        }

        else

        {

            RenderText("<th>empty grid</th>");

        }

    }

}

And now, the code for this view component turns into:

<?brail component GridComponentWithAutoGenerateColumns, {"source": contacts} ?>

So, in about 170 lines of code we created a grid components that gives you quite a bit of functionality. It is an basic grid component that we can configure quite liberaly all over the place. It supports paging seamlessly, and with a tiny bit of work, we managed to make it support AutoGenerateColumns in another 30 lines or so. The full code is here, feel free to poke around.

All in all, it took me about half an hour to write this View Component. Just to put this in perspective, I spent more time writing this entry...

Brail "new" feature, component sections...

I call it a "new" feature because it is something that the NVelocity view engine supports for quite some time. The basic idea is to allow this type of code:

<?brail

component BasicGridComponent, {"source": contacts}:

  section header:

?>

    <th>EMail</th>

    <th>Phone</th>

<?brail

  end

  section item:

?>

    <td>${item.Email}</td>

    <td>${item.Phone}</td>

<?brail

  end

end

?>

This feature open up some very interesting possibilities with View Components...

My OSS Stack

This includes only the stuff that I have need to change / modify, so stuff like log4net, NUnit, NAnt are not here, but they are certainly part of the stack :-)

(Image from clipboard).png

The Problem of Open Source in the Microsoft World

I hope that this post will reach more than the usual readers of this blog, so let me introduce my open source resume:

I am an active member (committer) of two big open source projects, NHibernate and Castle, own an open source project, Rhino Mocks (which is a part of Rhino Tools, a bigger OSS effort), and a semi-active member of an open source lagnauge on .Net, Boo. I am a heavy user of open source tools (Subversion, trac, log4net, nunit, nantcuyahoga, dasblog, to mention just a few).  I have been actively involved in the open source community in the .Net world for over three years.

I am not a zealot , you will not find me waving the GPL flag and stroming Microsoft HQ to liberate the captive code there. I do believe in open source software, and in the value of a community around the basic blocks of software.

The open source community in .Net is big, but it is only a fraction of the size of the open source community in other environments (Java, for instnace), compared to the number of users. This issue has been raised several times, it is certainly not a new one. Enough time has passed since .Net 1.0 was released to make the old excuses about ".Net is new", or "the Java guys has a lot more time to experiment with stuff" to lose any strength.

This disparity can be explained by looking at the basic facts of the .Net community. .Net has a central vendor (Mono is marginal at best), Microsoft. This puts Microsoft in a position where they have the ear of every .Net developer, team lead and architect (to say nothing about PHBs). And Microsoft isn't doing anything to foster a healthy OSS community around .Net.

What do I mean by not doing anything to help build an OSS community? Let us look at the Java land, and take a couple of OSS projects there, shall we? JUnit and Ant are two good examples, both of those are examples of projects built by the community, to solve problems that their developers were facing. What is the current status of those projects in the Java land? Well, they have excellent tool support by all the major IDEs, they are accepted as the way you do things in Java. This is a common theme in the Java world, actually. Hibernate and EJB 3.0 are another example, and I am pretty sure that I can carry on for quite a while.

Due to the distributed nature of Java (no single source, even though Sun can dictate stuff), the libraries and tools are competing on merit, and usually the best tools (best may also mean the first, btw) are accepted as the basis from which further work is done.

In .Net, however, the situation is far different. Let us take the same example  in .Net, we have both NUnit and NAnt in the .Net world. In 2005, Microsoft came with Visual Studio 2005, which included similar technologies to both NUnit and NAnt.

The answer to NAnt was MsBuild, which is based on the same principals of NAnt (xml based, declarative, extendable, etc). Now, to be fair to Microsoft, NAnt is GPL'ed, so technically they can't use it for Visual Studio. I am sure that they could have work something with the developers.

The answer to NUnit was MS Test, which has the same model as NUnit (attributes based, etc). It has incompatible syntax with NUnit (or any other .Net Unit Testing framework), and is severly limited compared to NUnit. In this case, NUnit has a commercial friendly license, so Microsoft could certainly have used it.

Now, a developer on the .Net platform has to choose between NUnit vs. MS Test, NAnt vs. MsBuild, etc. Microsoft's tools tend to come with a lot more tools, including fancy UI, wizards, etc. The problem is that when you need to make a change in those tools, you have a lot of wieght to move. Take for example the Abstract Test Case which MS Test doesn't support. At the core, it is an issue of removing BindingFlags.DeclaredOnly from the code that selects the test methods to execute. The problem is that Microsoft can't do that, they need to change the UI, the wizards, etc to be able to support this. Suddenly a very easy change turns into a big undertaking, with implications that can cost quite a bit of money and time.

You can see this pattern repeated over and over if you just take a look at the OSS tools that Microsoft is trying to replace with its own. Some quick examples from the top of my head:

  • NDoc and Sandcastle (again, NDoc is GPL'ed, again, I am pretty sure that they could have talked with the developer to change the license).
  • Log4net and the Logging Application Block.
  • Castle Windsor/Spring.Net and Object Builder.

I get the sense that a lot of time, a functionality that already exists in the open (often with license that allows commercial use) is being passed on because it is not from Microsoft. The only OSS Project that I know of that is going to be integrated into the toolset is the WIX installer, which is a Microsoft project.

What I would have liked to see is Microsoft working with the OSS community to provide better tools for developers based on the best-of-breed tools that already exists. There is nothing more annoying than having to learn (again) how to write a build script to automate the deployment of a project, but in MsBuild instead of NAnt. Or remembering to put [TestClass] instead of [TestFixture].

I do not want new products from Microsoft that does the same thing as existing OSS products. They don't have the same level of maturity as an OSS project that is several years old, and I hate the answer "Well, it may not do [critical feature that I need] like [oss does], but this is Microsoft, and it will definately do it in the next version." (which I got for several times, for several different products, from Microsoft people / consultants).

I think that saying this is tantamount to saying: "We built an inferior product, missing critical features that you need. We inversted in [better UI / integration with Office / etc] and didn't get to this. We are Microsoft, so you will use our stuff anyway, and maybe we will fix it next version". I want to see official Microsoft people recommending the use of OSS products like NHibernate, instead of saying "do it manually, or wait a year and do it in LINQ". There are a good number of projects that sprung up in the .Net ecosystem to fill in voids in what Microsoft is offerring. Duplicating this functionality is a waste of energy. Both for Microsoft and the community.

Microsoft should leverage the successful open source projects to make life easier for developers. The Java model is a very compelling one. Let us take leave of ours senses for a moment and assume that Microsoft has decided that it wants to add support for NHibernate in Visual Studio. What would happen? Better documentations, a lot more samples, probably better, easier tools. The core functionality would remain, and a whole new fucntionality would be added. Everyone would benefit (well, maybe except the DLinq team :-) ).

Returning to the real world, the OSS community in .Net biggest weakness is that the OSS community doesn't include Microsoft itself. And no, CodePlex doesn't really count. CodePlex doesn't bring Microsoft and OSS togetherer in the sense that it is not a place from which things go into the CLR or into the standard tool set. To take a simple example, the Mvp.Xml project. It contains functionality that is essential to heavy users of XML on .Net (of which I am not, btw). Was there any code migrated from Mvp.Xml to System.Xml? Would there be any such code?

As it stands today, I don't think that this is likely. I would like to change this attidute from Microsoft.

Some interesting links on this subject are from a discussion a few months back about whatever microsoft should financially support OSS projects (link 1, link 2, link 3).

The most fun part in talking technology...

I do a lot of communicating about technical stuff, sometimes with our own developer teams, sometimes with clients, and sometimes with just random dev groups that I get to meet (user groups, email, IM, etc).

Almost invariably, whenever I talk to them about the way they built their projects (I hate the word architecture), I got through the following stages:

  • This isn't how I would do this...
  • Oh, My God!
  • Why are you doing this??
  • Oh, I see.
  • Hm...
  • Just let me think about it a moment
  • So, what you are doing is actually XYZ beause of ABC.
  • Nice...

The best part of talking tech is that I keep learning so many new approachs to solve the same problems under different constraints.

Of course, there is another variant for the above scenario, Legacy code:

  • Bloody Hell! (someone please show me the exit, now).
  • I want the home address of the guy who wrote this file, oh, and a pair of thumb screws...
  • There goes the week/month/year...

 

Code in the Movies

There are a lot of reasons why I can't go to any movie that feature code/hacking in it... I like fantasy as much as the next D&D fan, but code in the movies is way off in la-la land. Drivl has the complete details

Tags:

Published at

Open Source Tidbit

I just gotten an email from a client that is using NHibernate. It was hard, getting them to use NHibernate. They had a lot of resistance to use something that is not Microsoft, and is open source to boot*. That email contained a fix for NH-736, which I closed some time ago, thinking it was fixed (it was, for queries, but not for entities).  I haven't got them to the point that they are making patches yet, but this looks like a very good step in the right direction.

* Yes, I know, I don't understand this approach either.

Tags:

Published at

Pitching Castle

As I mentioned, there is not a very interesting discussion on the Castle Developer mailing list.

One of the topics that just came up is evangelizing Castle to the community. I think that the main problem of Castle is that it help solves the problems that you have after you finished 30% of the project. That is when you start discoverring the limits of the stuff that MS is preaching. It takes prior experiance with this pain to make the trade off visible. I know that in the past I have talked about the seperation of UI / business logic that is inherent to MonoRail, and I got responses like: "Well, that is why we have code-behind files in ASP.Net".

I wasn't sure quite how to deal with that argument then. Every now and then I see people who are fortunate enough to build applications where the UI is truly just the ASPX and maybe a single line or two of databinding in the code behind. But my experiance is that I often need to do complex stuff in the UI. For instnace, show certain rows in a grid with a certain color, Ajax, etc. All of which are intimately tied to the UI, and are not possible to do in the ASPX. This means that they go to the code behind file, and there goes the Seperation of Concerns out the window. I have seen a date picker control that is over 2,500 lines of code. And even in this simple control, there was some business logic involved (mostly around what valid dates are, and how to handle ranges of them.

Anyway, this discussion coincides with a request from a friend to send some information about how to sell Active Record to their team lead / architects. I uploaded the presentation to my Presentations page, so feel free to start pitching Active Record (which is the easiest thing to get into a project, I have found) and then expand your Castle use later on.

 

Inappropriate Advetising, Take 2

Okay, now this is a major news site in Israel, Walla. I got click on a header about an escaped rapist, and the first thing I see is an ad of a girl stripping. Apperantly this has something to do with a cellular phone, but I fail to see the connection...