At one point, nearly five years ago now, I not only used DataGrids…. I liked them. I’ve learned a lot since then, I recall thinking the other day that Microsoft must have had a bit of an off year when they decided to release a web development platform which pretty much relied on the client having Javascript available.
Have you made any claims in the past which you’d like to own up to now? Or do you think any of the current fads of today are going to look foolish in five years time?
http://weblogs.asp.net varies in quality quite a bit, but it’s worth being subscribed just so you always catch ScottGu’s postings. But recently I’ve noticed the Visual WebGui blog. This is effectively a product blog - every post since February is a promo for the Visual WebGui tool. Is this what weblogs.asp.net is about? Should posts like this be a regular feature in the content of this community web site? Is it really in the interest of the community at large? Andrew Stopford also has a blog there, and while he talks about MbUnit a lot, his posts never feel like they were written by a marketing department. He also speaks on quite a range of subjects, so his blog doesn’t leave me with a bad taste in my mouth in the way the Visual WebGui one does.
I guess posters can write whatever they like, but it seems like a waste to turn a good community into an advertising platform.
Practical Generics: CrudController
June 20th 2008, 6:48 pm in .NET, C#, Development, NHibernate, Patterns, Snippet.
In my last post I discussed code reuse in the form of an abstract CrudController class: a means of providing create, read, update and delete actions for a given entity. In addition, that class provided the ability to work with an entity specification class to allow for filtered reads - which is just another name for search results.
I’m going to show C# code samples for building with a class like this, but you’ll have to fill in the gaps in terms of how you can work with it. The code to list entities is the most interesting and will demonstrate the concept best, so I’m going to focus on that. To begin with, let’s assume a very simple entity:
public class Post
{
public DateTime CreatedOn { get; set; }
public string Headline { get; set; }
public string Body { get; set; }
public string Username { get; set; }
}
So, to begin with we’d like to list Posts. A typical method to do so would be:
public void List()
{
PropertyBag["posts"] = PostRepository.FindAll();
}
But remember that in my case, I’m trying to create a reusable method of doing this, and that I’m also going to be working with ExtJS which is going to consume JSON. So, I have the following class:
public abstract class CrudController<Entity>
{
private IRepository<Entity> _repository;
public void GetJsonList()
{
RenderText(
JsonHelper.Serialize(_repository.FindAll())
);
}
}
public class PostController : CrudController<Post>{}
I need a shell PostController, but most of the action is happening in the CrudController, and I’m using the magic of Windsor and generics to make it happen. By passing Post as a type parameter to CrudController, Windsor will then give me the correct IRepository<T> to work with, and from there it’s a simple matter of fetching the list of Post Entities in the same way I did in the previous code sample. I want to get a JSON string back, so I’m passing that list to a helper to serialize to JSON.
The next step is to make this listing method a bit more flexible and a bit more powerful. I want to do a couple of things - paging, sorting, and searching. Here’s my new method signature for GetListJson:
void GetListJson(int start, int limit, string sort, string dir, EntitySpecification spec)
The arguments “start” and “limit” are for paging, saying which record I should start from and how many I should return. The “sort” argument tells me the column I should sort on, and “dir” gives me the sort direction. But what about EntitySpecification? Let’s show it in context:
public abstract class CrudController<Entity, EntitySpecification> where EntitySpecification : ISpec
{
private IRepository<Entity> _repository;
public void GetJsonList(int start, int limit, string sort, string dir, [DataBind("spec")]EntitySpecification spec)
{
spec.AddOrder(sort, dir);
spec.FindAll(_repository, start, limit);
}
}
public class PostController : CrudController<Post, PostSpecification>{}
As you can see, EntitySpecification is databound by Monorail; incoming parameters are passed to the specification to build up a criteria for querying, as described in Ayende’s search specification post. That means that I don’t have to explicitly handle searching in my CrudController at all, because it’s all handled by the EntitySpecification. A sample PostSpecification could look like this:
public class PostSpecification : ISpec
{
private ICriteria _criteria;
private string _username;
public virtual string Username
{
get { return _username; }
set {
_username = value;
if (value == null)
return;
_criteria.Add(
Expression.Eq("Username", value)
);
}
}
public void AddOrder(string sort, string dir)
{
var order = (dir == "ASC" ? .Order.Asc(sort) : Order.Desc(sort));
_criteria.AddOrder(new Order());
}
public IList<Post> FindAll(IRepository<Post> repo, int start, int limit)
{
repo.Find(_criteria, start, limit);
}
}
When Monorail runs the databinder, the Username property’s getter will be called and the private criteria will be altered. When the specification’s FindAll method is called, that criteria is passed through to filter the returned records.
Let me know if you have any improvements or suggestions, and thank you again to Ayende for the specification ideas.
Mirvoda Sergey has announced NHAML for Monorail. Andrew Peters brough NHAML to ASP.NET MVC last year, and now us Monorail users can enjoy using a very different kind of templating engine to the others available for Monorail. Check out this HAML tutorial if you’d like to familiarise yourself. Thanks to Mirvoda Sergey!
After my earlier post on JS generation from C#, I wanted to investigate my options. Although zproxy highlighted the jsc project, I wanted to focus on a real world scenario first and so I’m looking at ExtSharp, which relies on Script#, a project which will “compile your C# source code into JavaScript”.
ExtSharp leverages Script# to allow you to write ExtJS applications in C#, which was my target when I began thinking about JS generation. I’d like full intellisense, documentation and compile-time checking when working with this rich framework. Will ExtSharp give me that?
Downloading ExtJS2Samples-v2.0.1.zip from the Google Code site gives me a solution of samples. Here an interesting implementation issue arises - all of the actual C#-Javascript class files are in a separate project to the .aspx pages which display them. This is down to necessity; Script# uses an assembly called sscorlib which, bizarrely, seems to provide its own implementations of many of the .NET types found in the mscorlib assembly.
This separate project also runs an MSBuild targets file from Script# which runs after main compilation to compile the C# into Javascript. Straight away I’m seeing two bits of magic - sscorlib and post-build events - which I’m not too keen on. But the solution builds, and after changing the web.config references to nStuff.ScriptSharp.Web to 0.4.5.0, I am able to view the samples.
Based on my earlier post, I was interested in the Window sample, but unfortunately that didn’t work. The array Grid one did though, and it operated just as the ExtJS website sample does. Many of the other samples are missing, which is disappointing; of the ones which are present, most work very well. Overall, I was encouraged, and I moved on to looking at the C# code which was generating these samples.
Let’s look at how a ColumnModel is built when working in Javascript:
var colModel = new Ext.grid.ColumnModel([
{id:'company',header: "Company", width: 160, sortable: true, dataIndex: 'company'},
{header: "Price", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
{header: "Change", width: 75, sortable: true, renderer: change, dataIndex: 'change'},
{header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
{header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
]);
I think that’s pretty concise - there’s not a lot of cruft. Now the ExtSharp version:
ColumnModel colModel = new ColumnModel(new Dictionary[] {
new Dictionary("id", "company", "header", "Company", "width", 160, "sortable", true, "locked", false, "dataIndex", "company"),
new Dictionary("header", "Price", "width", 75, "sortable", true, "renderer", new MoneyRenderer(Format.usMoney), "dataIndex", "price"),
new Dictionary("header", "Change", "width", 75, "sortable", true, "renderer", new ColumnRenderer(change), "dataIndex", "change"),
new Dictionary("header", "% Change", "width", 75, "sortable", true, "renderer", new ColumnRenderer(pctChange), "dataIndex", "pctChange"),
new Dictionary("header", "Last Updated", "width", 85, "sortable", true, "renderer", Format.dateRenderer("m/d/Y"), "dataIndex", "lastChange")
});
Hmm. Lots of strings - I’m not keen. This is one of two methods of providing a configuration to an Ext class, the second of which involves a specific config class:
Ext.grid.GridPanel grid = new Ext.grid.GridPanel(new Ext.grid.GridPanelConfig()
.el("grid-example")
.ds(ds)
.cm(colModel)
.autoExpandColumn("company")
.height(350)
.width(600)
.title("Array Grid")
.ToDictionary()
);
Unconventional style, to say the least, but at least it’s properly typed. This is pretty far away from my ideal API for this kind of thing. Let’s look at how this is turned into Javascript.
As I previously mentioned, the Script# project contains MSBuild targets which generate the JS code after the build is complete. This code can then either be referenced directly, or via some ASP.NET controls from your ASPX pages. As well as your own generated code, you must also reference a couple of Script# files and a wrapper file for Ext itself. That wrapper file is actually what makes everything work here - rather than your C# code being converted into something which works with the Ext library, it instead only works with the Ext wrapper provided by ExtSharp.
Looking at the ExtSharp project overall, I’m not a convert. There are too many layers between your C# and where it finally touches the “real” Javascript:
1. Your generated JS
2. ExtSharp JS wrapper
3. Script# utility JS
The C# API is also pretty horrible - certainly not in my style but also far from being an API I recognise from any other project I’ve worked on. Whether this is a style choice or due to technical limitations, I’m not sure.
The ExtSharp project definitely drew my curiosity, and could hold promise. In its current state, I wouldn’t consider using it in a project of my own, as the API is not strong enough to make me swap from native Javascript. Still, I will continue to follow future work with interest.
Javascript Generation - A Change Of Heart
April 2nd 2008, 3:03 pm in .NET, C#, Development, Ext, Javascript.
I’ve previously talked about my dislike for code generation in Javascript. I still standby that, but I am beginning to have a change of heart for certain scenarios. I’ve been working on a couple of ExtJS applications recently and I’ve got lots of code which is purely ExtJS stuff on its own - no HTML or other code in there really. It’s been a project where I’ve been using C# 3 and it’s partly the similarities between the two languages which have triggered this rethink.
Take a look at this code:
var win = new Ext.Window({
title: 'Order Viewer', layout: 'border',
width: 500, height: 500,
modal: true, resizable: false, closable: false, draggable: false,
items: [ frm, lst ]
});
win.on('render', function() {
load(5);
});
win.show();
That’s pretty standard stuff for what I’m doing with Ext right now - I create a new window with a load of configuration options, then add in an event handler for the window’s render event, and finally show the window on screen. Now imagine that you could write the following in C# 3:
var win = new Ext.Window{
Title = "OrderViewer", Layout = Layout.Border,
Width = 100, Height = 200,
Modal = true, Resizable = false, Closable = false, Draggable = false,
Items = new [] { frm, lst }
};
win.Render += delegate {
load(5);
};
win.show();
As far as I’m aware, all of the above is valid C# 3 code. I’ve basically written it as I’d like to use it, with an enum for the Layout type, and C# style event handler syntax, but the interesting thing to me is how very similar it is to the Javascript version.
The ExtSharp project allows you to write your Ext code in C# and have it rendered as Javascript. I’m going to explore it in my next post, and examine how closely it can be made to fit the code sample above.
I’m starting work on a new project on Monday and I’ve got full control of all development aspects. With that in mind, I’ve been thinking of how I can get to beta status as quickly as possible - finish main development and get to the stage where the client is reviewing minor details. This is dependant on a combination of my skillset and the tools I’m going to use. I’ve got:
- Existing Plastiscenic.Commons code and project structure for quick setup
- C# 3.0 to remove some boiler plate code (automatic properties for example)
- Monorail to develop with fewer LOC in the main app
- NHibernate for low friction database work
- ExtJS for rich backend
- Strong cross-technology skills to integrate the above
Are there any additions to this that you use to accelerate the development process?
Finders with DetachedCriteria
December 17th 2007, 3:57 am in .NET, Active Record, C#, Castle, Patterns.
I should file this under “things that are probably a design pattern but I’m not sure exactly what kind”; it seems like one of those typical things that you will naturally stumble upon when using the Repository pattern and indeed when you start to separate out your query logic.
DetachedCriteria is an “offline” version of the NHibernate Criteria class, used to build up Criteria where an NHibernate Session is not available. The NHibernate documentation has more on how to use DetachedCriteria on its own, but I want to talk about inheriting from it to create a simple custom finder class.
Say we have a Active Record Person class, with height and weight properties:
[ActiveRecord]
public class Person : ActiveRecordBase
{
[PrimaryKey]
public int Id { get; set; }
[Property]
public int Height { get; set; }
[Property]
public int Weight { get; set; }
}
The height and weight properties are simplified, and I’m using C# 3.0 automatic properties for clarity. I want to search for a Person based on their height and weight, so to do so, I’ll create a new finder class:
public class PersonFinder : DetachedCriteria
{
public class PersonFinder(height, weight) : base(typeof(Person))
{
Add(Expression.Eq("Height", height));
Add(Expression.Eq("Weight", weight));
}
}
A simple class, but it clearly states its purpose. Here’s how it could be used:
Person.FindAll(new PersonFinder(200, 300), new Order("Id", true));
For me, the advantage of this code isn’t just in reducing what you have to type. Instead it is in the readability and discoverability of the code.
I love it when a plan comes together (a tale of Monorail, ActiveRecord and ExtJS)
October 8th 2007, 11:10 pm in .NET, Ajax, C#, Castle, JSON, Javascript, Monorail, Screencasts.
I’ve blogged before about the enabling features of Monorail and Active Record, part of the Castle stack. Another piece of software which is making my development life a pleasure is ExtJS - a collection of javascript goodies created by Jack Slocum and his team - and when these three things come together, watch that coding fly…. I’ve created a screencast in which I demonstrate how easy it is to build a paging, sorting, filtering, AJAX-powered grid using ExtJS and Castle, and you can watch it here. It’s 20 minutes long but filled with goodness - and a couple of hacks (forgive me :). Don’t forget to check out all my past screencasts too.
UPDATE: As requested in the comments, you can MonorailExt1 VS Project directory of this.
For a few months the term “ALT.NET” has been gaining traction on the blogs I read, starting from a post by David Laribee in April. From there it has taken off, with an ALT.NET Conference taking place this week. So it’s perhaps timely that Sam Gentile has written a post entitled “Goodbye CodeBetter and ALT.NET” which talks about the ALT.NET movement and some of the people surrounding it.
ALT.NET is Divisive
ALT.NET is a divisive thing. No matter what they tell you.
So says Sam, and I’m in agreement. The ALT.NET conference is so cliquey that it hurts, and that’s really highlighted by an interesting bit of news that came out yesterday regarding Microsoft’s upcoming MVC framework. I think it’s interesting that they’d talk about it at a conference where most of the people will already be using this sort of technology. Just as I find it pointless that you’d go to a conference to discuss the stuff that everyone there already knows. DDD, BDD, MVC - these aren’t things that will be unknown to people attending the ALT.NET conference.
ALT.NETter A: so… heard of that new BDD business?
ALT.NETter B: Yep.
ALT.NETter A: Oh, well there’s this great new idea called DDD!
ALT.NETter B: Yeah, right into that too.
ALT.NETter A: Oh.
And so on. But wouldn’t that conversation have been a whole lot more interesting if the second developer hadn’t heard of those ideas?
The View from on High
The ALT.NET conference is barely about the underlying technologies or ideas. It mainly serves to allow all of the ALT.NET developers to come together to talk about how great it is that they are all ALT.NET. Us, and them. Back to Sam:
I am not going to use the term “Morts.”
Good, because it’s an offensive term, but it’s one that’s being thrown around by the ALT.NET gang with abandon. Scott Hanselman, a great blogger, had this to say from the conference:
Mort is crying because mommy and daddy are fighting.
That’s the kind of patronising way in which the term is being used; I mean come on, the damn thing is short for “mortal” which is a pretty clear indication of how the people who use “mort” think of themselves: Gods of their domain. Overseers of the lower developers who haven’t had the resources, or the guidance, to work with the fantastic array of non-Microsoft technologies that exist.
And in order to address that imbalance, the ALT.NET mob organise an enormous desert circle-jerk, and I call bullshit. If they really wanted to change things then they should be writing about their techniques in detail, coming up with introductory guides to DDD, TDD, mocking, creating screencasts, or giving talks at mainstream conferences, or producing tools to make the level of entry to these technologies lower than it is.
Abandon ALT.NET - Before it Goes Too Far
A lot of people in the ALT.NET camp may not feel that they’re being divisive but I can tell you that by propagating this idea you’re creating a line in the sand, with the highly-knowledgable on one side and the masses on the other. You’re not encouraging dissemination of your information, you’re just creating another impenetrable gang of developers that is almost opaque to the guy on the ground.
UPDATE: I’ve updated this post on my LosTechies blog - see Why ALT.NET?