Archive for May, 2008

QUnit: love it!

May 28th, 2008

If you were looking for a way to test js, and like me, found jsunit a bit too weird to use, go with QUnit. It’s easy to get started and easy to keep all tests organized. I plan to record a screencast on how to use it soon.

qunit1.png

Categories: General | Top Of Page | 2 Comments » |

Migrations patch

May 28th, 2008

As promised, here it is. Some comments about the changes

- Had to change the way tables names were used on the CREATE/DROP/ALTER statements, removed quotes to allow you to define the schemas. I use Core.Comment, Tracker.Team as lot.
- Made Connection available to the migration class, as you would need it to perform sql operations using same transaction
- Introduced the SchemaBuilder
- Added support for unique keys (still need to support Defaults, though)

For donjon, I’ve also created a Castle ActiveRecord integration, so the migration reuse the connection/transaction support. It’s not nice as I would like it to be as it involves creating a SessionScope for the migration run, but works well. I’ll try to make that available in a near future.

Categories: General, OSS | Top Of Page | 3 Comments » |

MR and Windsor set up screencast

May 26th, 2008

Quick, dirty and unrehearsed. Just show how to set up MR without external configuration, how to get Windsor integration enabled and setting up routing. Created to test Screenflow.

Mov file

Machine.Migrations is freaking sweet

May 22nd, 2008

Update: patch is here, but nevertheless it was applied already.

First of all, yes, I’m a Family Guy’s fan, if you haven’t noticed yet.

To dig into Machine.Migrations has been on my to-do list for a while. After another error due to a missing schema on one of our projects, I moved it to a higher priority. Jacob’s introduction might be a good start, but really haven’t done it for me. So I grabbed the source and started to navigate.

Sure, I have some nitpicks about it, but overall it’s a beautiful piece of code. SoC nicely applied.

My requirements, however, are a bit different. I dont want my clients running migrations tasks, I want my project automatically updating the schema to reflect the latest model. As the project is modular, each module has its own schema version. So instead of inspecting the file system, I’d inspect assemblies. Versions wont come from file names, but from a class name from an attribute.

Twenty-minutes later I got it changed to support that, basically adding new implementation for two services.

Then I started to convert my old migration scheme (rudimentary) to the 001 migration for one of my modules. Something like:

Schema.AddTable("Company",
                new Column[]
                    {
                        new Column("Id", typeof(int), 8, true),
                        new Column("Name", typeof(string), 20), 
                    });

Schema.AddTable("Project",
                new Column[]
                    {
                        new Column("Id", typeof(int), 8, true),
                        new Column("Name", typeof(string), 20), 
                        new Column("Description", typeof(string), 20), 
                        new Column("Url", typeof(string), 20), 
                        new Column("CompanyID", typeof(int)), 
                        new Column("`Key`", typeof(string), 12), 
                    });
Schema.AddForiegnKeyConstraint("Project", "FKProject_Company", "CompanyID", "Company", "Id");

Schema.AddTable("User",
                new Column[]
                    {
                        new Column("Id", typeof(int), 8, true),
                        new Column("UserName", typeof(string), 30), 
                        new Column("Email", typeof(string), 20), 
                        new Column("FullName", typeof(string), 20), 
                        new Column("Password", typeof(int)), 
                        new Column("`Key`", typeof(string), 12), 
                    });

Ok, not cool. Too many strings, too error prone. I’m a firm believer that software can be made smart and help you where it’s possible.

So I changed it to

SchemaBuilder builder = new SchemaBuilder(Schema);

TableBuilder company = builder.AddTable("Company", 
        Columns.PrimaryKey<int>("Id").Identity(),
        Columns.Simple<string>("Name", 25)
    );

builder.AddTable("Project",
        Columns.PrimaryKey<int>("Id").Identity(),
        Columns.Simple<string>("Name", 25),
        Columns.ForeignKey("CompanyID", company)
    );

builder.AddTable("User",
        Columns.PrimaryKey<int>("Id").Identity(),
        Columns.Simple<string>("`Key`", 15).MakeUnique(),
        Columns.Simple<string>("Name", 25),
        Columns.ForeignKey("CompanyID", company)
    );

Let me know if you like it, so I can make the patch file available.

Categories: General | Top Of Page | 12 Comments » |

Credits: be nice

May 22nd, 2008

I was surprised to see that Moq uses Castle’s DynamicProxy, there is no indication anywhere on the site or even in the source repository or distribution, the assembly is merged. The same is true for Rhino.Mocks. You’d have to actually dig the IL or dig into the source code to see the dependency.

Yeah, I am very aware that they are not obligated to give this credit. Apache License is very permissive. But it would be so nice if they acknowledge this, like NHibernate does. And someone has said, niceness is the currency of open source.

Categories: Castle | Top Of Page | 17 Comments » |

Travelstar 7K200

May 20th, 2008

Just installed the Travelstar 7K200 on my MBP, and restored the backups. If you still using a 5400 rpm HD on your laptop, and you care about productivity, go ahead and buy it.

Installing it on a MBP is fun. You need to use precision tools – I had to buy a set – and prepare your patience. iFixIt has excellent guides.

First thing you’ll notice, the HD is completely silent. To the extend that I thought it wasn’t working when I booted after installing it.
Then you’ll notice the speed. Windows and Mac booting are faster, opening apps is faster. So cool!

The manufacturer claims that the Travelstar 7K200 is faster than other 7200rpm HDs. I’d say that would be hard to tell, but it’s certainly a great performance improvement for a laptop. Another tip: buy a 2.5 Sata USB Enclosure, so you keep using the old HD.

Categories: MacBook | Top Of Page | 2 Comments » |

Some clarifications regarding Castle’s presentation

May 18th, 2008

Gojko posted the slides after his presentation. I thought I should just make some clarifications:

But it is a RC! – A bad marketing decision

Hmm, well, it could be perceived as a bad marketing decision, but there are some things preventing us from getting 1.0 out, and I have blogged about them. Even worst, I’ve switched priorities and I’m working to get our first product, donjon, in a beta stage. And to make things more complicate, a team member left just when we signed a few more projects in.

My attention to castle right now is tending to zero, as people might have noticed on the mailing list, but hopefully this is going to change real soon.

ActiveRecord

I don’t encourage people to use AR with the AR base class. Use the ARMediator and use the repository pattern or a dao pattern to increase isolation and testability.

MonoRail: Layouts

Layouts can be set through attributes or using the LayoutName or LayoutNames exposed by the ControllerContext (trunk version) or on the Controller class (RC version).

MonoRail (-) : Hashmap for view properties

On MonoRail we usually use a less static typed template engine, such as NVelocity and Brail. So you have a bridge to cross between the controllers (static typed) and the view (dynamic). MR could offer alternatives for people using more static typed engines, such as AspView.

MonoRail (-) : Windsor Integration a bit too complicated

Really? The trunk version even free you from having to set “windsorIntegration=true” on the web.config, so I dont think it’s complicated at all. I’d be interesting in hearing/reading more on this, and how we can make it simpler then…

Other than that, kudos to Gojko for putting together a great presentation!

Categories: Castle | Top Of Page | 10 Comments » |

Autoregistration without Binsor

May 13th, 2008

On my Global.cs I usually have:

private static void RegisterWebComponents()
{
    container.Register(AllTypes.Of<SmartDispatcherController>().
        FromAssembly(typeof(HomeController).Assembly));

    container.Register(AllTypes.Of<ViewComponent>().FromAssembly(typeof(Global).Assembly)
            .Configure(
                delegate(ComponentRegistration reg)
                {
                    reg.Named(reg.ServiceType.Name);
                }));

}

To get Windsor integration:

First, make the Global implement the IContainerAccessor

public class Global : HttpApplication, IContainerAccessor

Then add a static field to hold the container

private static WindsorContainer container;

The App_Start/End and the IContainerAccessor implementation:

protected void Application_Start(object sender, EventArgs e)
{
    container = new WindsorContainer(new XmlInterpreter());
    container.AddFacility("mr", new MonoRailFacility());

    RegisterWebComponents();
}

protected void Application_End(object sender, EventArgs e)
{
    container.Dispose();
}

public IWindsorContainer Container
{
    get { return container; }
}

To Configure MonoRail using code

Make the global implement IMonoRailConfigurationEvents and implement the method Configure:

public class Global : HttpApplication, IContainerAccessor, IMonoRailConfigurationEvents
{
    public void Configure(IMonoRailConfiguration configuration)
    {
        // Configuring ViewEngine
        configuration.ViewEngineConfig.ViewPathRoot = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views");
        configuration.ViewEngineConfig.ViewEngines.Add(new ViewEngineInfo(typeof(NVelocityViewEngine), false));

        // You can configure other things, and hopefully in the future 
        // we can expose a kind of fluent interface to guide you on this process
    }
}

VS.Net support for js libs

May 13th, 2008

What? I’m reading this and I cannot believe! I’m seeing jQuery intelisense in VS.Net or my eyes are tricking me?

I couldn’t find a list of the bugs fixed, but I hope the css editor was also fixed. It crashes on us quite regularly with “cannot read from shared memory” or something like that. Then decided to switch to standard text editor for css.

Well, THANK YOU people at building 42 and 31. Great stuff!

Categories: jQuery | Top Of Page | 1 Comment » |

MonoRail with RoutingEx on IIS7

May 9th, 2008

It takes some time to figure out how IIS7 performs its handler/module matching, and to realize that the ordered list not always reflect the real order – once you set up an order click on View Unordered List and back to View Ordered List to see if it really changed to reflect what you want.

And one complain: it would be a lot easier if IIS7 and their handlers/modules could work together to identify if the handler/module was able to deal with the request or not, this is especially true for the DefaultDocumentModule. More on that later

This is how the handlers should look (in the ordered view)

iispanel.png

Steps

First of all, I’m using Vista Ultimate, so from what I’ve read, the integrated mode doesn’t work yet, so fall back to Classic mode.

After creating the web site or virtual folder, go to Handler Mapping and

  • Delete the handler for static files Empirical reason, I can be wrong: I wasn’t able to re-order this one as it seems to inherit from a parent configuration, deleting it saves a lot of hair
  • Add a new Module Mapping, request path: *.*, Module StaticFileModule, Restrictions: File and GET verb. I call this one StaticF
  • Add a new Script Map, request path *, Executable aspnet_isapi.dll (the whole path), name: MR. On the restrictions, uncheck the Invoke handler only if request is mapped to (maybe you could mark Folder, not sure if IIS is going to check if the folder actually exists, that would be a problem)

Now order the handlers. In my case I have a default.aspx, so I make the .aspx handler the first one.

Then you, as you dont want MonoRail handling static content, you make StaticF the next one

Finally MR handler should handle the rest of the requests.

I struggled for some time to get the DefaultDocumentModule working. The problem is that it conflicts with MR handler in its restrictions. You basically want that it handle a folder request, and redirect to one of the default document (if found). What actually happens is that it will greedily take all requests. Leaving no room for MR handler. The fix for that is changing MonoRail routing to be able to handle empty folders requests and matching a PatternRoute, something that today is not possible.

Let me know if that works for you.