Monday, 23 February 2009
Get busy in the community
Friday, 20 February 2009
Pragmatic LINQ
LINQ, especially when talking to a database (or other back-end), arguably creates a bit of a tricky mess for proper application design.
Consider:
- I'm strongly in favour of proper unit testing
- As such, I like the repository pattern, since this allows me to mock my DAL
- In reality, I don't really need true POCO support; if I start needing my app to work with MySQL, I have bigger problems than POCO
- I like that LINQ-to-SQL / EF can maintain a basic object model for me
- Since it doesn't buy me anything, I don't really want to declare and maintain a "pure" (i.e. separate to the DAL) object model - I'm generally content to use partial classes to extend the classes we have generated
- For use in things like MVC, I want to know when data access happens; I don't want my view messing with lazy navigation properties
- I'm content (at the minute) to have a DAL that includes the LINQ-generated classes, the repository interface, and a class implementing that interafce, and think of it as "my object model assembly that happens (by coincidence) to contain a default repository implementation" (try saying that twice...)
- While I'm happy to know that LINQ to SQL supports POCO usage, the tooling doesn't make it easy. For now, I'm content to use attributed classes, and get on with the job...
So what?
Well, the first impact this has is: if you want it to be testable in any real sense, there isn't a lot of the LINQ stuff that can make it into the public API. For example:
- the data-context - has nothing to do with external callers in a repository implementation
- navigation properties - very quickly start crossing aggregates and/or causing lazy behaviour (not good if your context no longer exists)
My current thinking with this is that the data-context and most navigation properties should be marked as internal to the data layer (trivial either in the designer or dbml views). This means that your repository implementation can use the navigation properties to construct interesting queries, but the public API surfaced back to the caller doesn't include them. If the caller gets and order from the order repository, and wants details about the customer: tough - go and ask the customer repository. There is an edge-case for tightly coupled data (order header/details being a prime example), where it might be prudent to leave the navigation property public - but this is in the same aggregate, so this isn't a problem.
It isn't whiter than white - but it seems pretty workable:
- The repository interface protects our data-context from abuse; we know what use-cases we are supporting, and that they have been tested
- The lack of navigation properties means we know when data access happens : it is when the caller asks the repository
The bit where I'm a bit mixed is in the subject of allowing the caller to use Expression arguments on method calls; the ability to pass in an Expression<T,bool>-based predicate is powerful, but risky: we can't validate that our DAL covers all use cases (due to unmapped method calls etc), and we can't be 100% what TSQL is going to execute in reality (even small composed expressions can radically change the TSQL expression). I think I'd need to evaluate that on a need-by-need basis.
I don't know if I'm saying anything a: obvious, or b: stupid... but that is my thinking...
LINQ to SQL - not quite dead yet...
I've happily gone on-record to say that in their current form, I believe that LINQ to SQL is a more useful tool that Entity Framework. Obviously, with the planned road-map to prioritise the latter (hopefully back-filling with the missing features that shipped with LINQ to SQL), this puts me on a back foot - so no doubt at some point (in the 4.0 era) I'll need to re-check my position.
However, I was very happy to get a "connect" e-mail today, telling me that they've fixed a bug I reported in LINQ to SQL, and that it would ship with 4.0; conclusive proof that it isn't completely side-lined, and continues to be a supported product (albeit with a reduced development effort). The only downside is that this makes it much harder to know when to make the switch... but I won't begrudge Microsoft that.
For now, at least, I breath the contented sigh of the developer who knows that their data-access works today and (in theory) tomorrow.
Thursday, 12 February 2009
Fun with field-like events
UPDATE: this all changes in 4.0; full details here.
Field-like events; a great compiler convenience, but sometimes a pain. To recap, a field-like event is where you let the compiler write the add/remove methods:
public event EventHandler Foo;
All well and good... the C# compiler creates a backing field, and add/remove accessor methods - however, the C# specification also dictates that the accessor methods will be synchronized. Unfortunately, the ECMA and MS specs disagree how. The ECMA spec maintains that the "how" is unimportant (an implementation detail) - the MS spec dictates "this" for instance methods, "typeof(TheClass)" for static methods. But if you follow the ECMA spec, there is no reliable way of independently using the same lock - you simply can't guarantee what it is (the C# spec doesn't mention [MethodImpl], so using this would also be making assumptions).
Aside: best practice is not to lock on either "this" or a Type - since in both cases you can't guarantee who else might be using the same lock.
Of course, in most cases this is irrelevant. Most classes simply don't need thread safety, and it is pure overkill. However, I was dealing with a case earlier where thread-safety was important (it is a class for simplifying fork/join operations). For convenience, I wanted to provide both regular event accessors and a fluent API to do the same - i.e.
class Bar {
public event EventHandler Foo;
public Bar AddFoo(EventHandler handler) {
Foo += handler;
return this;
}
// snip
}with fluent-API usage:
new Bar().AddFoo(handler).Fork(action).Fork(action).Join();
So what broke? The C# spec also dictates that inside the type, all access goes directly to the field. This means that the usage inside the AddFoo method is not synchronized. This is bad. So what can we do? My first thought was to use a nested class (since this is then a different type):
class Bar {
public event EventHandler Foo;
public Bar AddFoo(EventHandler handler) {
BarUtil.AddFoo(this, handler);
return this;
}
static class BarUtil {
internal static void AddFoo(
Bar bar, EventHandler handler)
{
bar.Foo += handler;
}
}
// snip
}Unfortunately, it turns out (by inspection) that this still uses the field directly, so isn't synchronized. If we make it non-nested, it finally works correctly - but then we're getting into the position where it simplifies things to just have an extension method:
class Bar {
public event EventHandler Foo;
// snip
}
static class BarUtil {
public static Bar AddFoo(
this Bar bar, EventHandler handler)
{
bar.Foo += handler;
return bar;
}
}As it happens, I decided to just side-step the whole debacle instead and do the locking myself...
Summary: field-like events; unnecessary synchronization when you don't need thread-safety, and highly questionable synchronization when you do need it...
Wednesday, 11 February 2009
Async without the pain
I've seen a number of questions lately about async operations recently, which (coupled with some notes in a book I'm proof-reading) have made me think a lot about async operations. I'll be honest: I often don't use async IO correctly, simply because it isn't friendly.
Basically, async is hard in .NET - at least to get right. One common alternative to avoid this pain is to use the synchronous version of code, but on a pool thread - i.e.
ThreadPool.QueueUserWorkItem(delegate { /* do stuff */ });However, while this is fine for many cases, it uses threads... we'd much prefer to use completion ports etc, which we can only really usually do by using the proper Begin/End methods that many IO wrappers provide.
So why is this a problem? Simply - you need to mess with IAsyncResult, instances, exception handling, etc. It soon gets messy. But are we missing a trick? Why can't we wrap this using functional programming?
For example, consider the following:
static void Main() {
HttpWebRequest req = (HttpWebRequest)
WebRequest.Create("http://www.google.com/");
RunAsync<WebResponse>(
req.BeginGetResponse, req.EndGetResponse,
ProcessResponse);
Console.WriteLine("Running...");
Console.ReadLine();
}
static void ProcessResponse(WebResponse resp) {
using (StreamReader reader = new
StreamReader(resp.GetResponseStream())) {
Console.WriteLine(reader.ReadToEnd());
}
}That doesn't look scary at all; we've hidden all the grungy details behind the opaque RunAsync method, using delegates - but we're using the proper (IO completion-based) async handlers. Here's the RunAsync method(s) - a little trickier, perhaps, but we only need to write it once - the point is that it can be used for any async Begin/End pattern (although we'd probably need to add a few overloads for common method signatures):
static void RunAsync<T>(
Func<AsyncCallback, object, IAsyncResult> begin,
Func<IAsyncResult, T> end,
Action<T> callback,
Action<Exception> exceptionHandler) {
RunAsync<T>(begin, end, callback, null);
}
static void RunAsync<T>(
Func<AsyncCallback, object, IAsyncResult> begin,
Func<IAsyncResult, T> end,
Action<T> callback,
Action<Exception> exceptionHandler) {
begin(ar=> {
T result;
try {
result = end(ar);
} catch(Exception ex) {
if (exceptionHandler != null) {
exceptionHandler(ex);
}
return;
}
callback(result);
}, null);
}
We could probably also do something similar using a fluent API, but to be honest the above makes it simple enough for me to use...
All of which will be handy when/if I finally get around to writing an RPC client/server for protobuf-net...
-----
UPDATE: further work has shown that having two actions (result and exception) is ugly; a far more useful pattern is to take a single action; Action<Func<T>gt; (for methods with return values) or Action<Action> (for void methods). The idea is that the original caller can invoke this function to get either the value or the exception (thrown):
public static void RunAsync<T>(
Func<AsyncCallback, object, IAsyncResult> begin,
Func<IAsyncResult, T> end,
Action<Func<T>> callback) {
begin(ar => {
T result;
try {
result = end(ar); // ensure end called
callback(() => result);
} catch (Exception ex) {
callback(() => { throw ex; });
}
}, null);
}
static void ProcessResponse(Func<WebResponse> result) {
WebResponse resp = result();
using (StreamReader reader = new
StreamReader(resp.GetResponseStream())) {
Console.WriteLine(reader.ReadToEnd());
}
}
This is illustrated further here.
Thursday, 15 January 2009
Collection Initializers, Events and Variables
Collection initializers are very neat. Great for regular code, but also quite handy for writing minimal demo code... for example, consider this recent winforms example for displaying a button on a form:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form
{
Text = "Hello world",
Controls =
{
new Button
{ Text = "Change title" }
}
});
}
What's wrong with that? Events and variables: collection initializer syntax doesn't allow you to subscribe events, and even if it did, we wouldn't have a convenient reference for each of the items (the form, the button, etc) to talk to.
The good news is that there is a simple fix; it isn't especially magic or clever - I'm simply repeating it here becaues I've seen a couple of people surprised by it. Basically, we can get the collection initializer to assign some variables for us - but we need to be a little sneaky because the language specification deliberately disallows assignment expressions from collection initializers (to avoid ambiguity with member assignments in object initializers). So how? Simple: brackets:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Button button;
Form form = new Form
{
Text = "Hello world",
Controls =
{
(button = new Button
{ Text = "Change title" })
}
};
button.Click += delegate
{
form.Text = "New text";
};
Application.Run(form);
}
Points to note:
- We declare variables for the objects of interest
- We assign the variable in the collection initializer, but surround the assignment in brackets (making the result a non-assignment expression)
- We still get definite assignment checking for free
- We can "capture" the variables in anonymous methods / lambdas as normal
- We can assign multiple variables in the same overall statement
Not huge, but one of those small things that might make things easier! The same approach will work with any collection initializer - winforms is just a commonly understood example.
Wednesday, 14 January 2009
Above The Surface
Or how I got my grubby paws on some very cool kit ;-p
In December 2008, I somehow landed a fantastic opportunity; to spend some time working in the Microsoft Technology Centre (MTC) lab in Reading, UK - on a prototype project for Microsoft's new baby: Surface. This prototype was timed for BETT 2009, the UK's (and quite possibly the world's) largest education exhibition: with ~28,000 visitors last year, this is a high-profile way for RM, Lightbox and Microsoft to communicate with the key educationalists and decision makers.
What was the project?
The aim was to demonstrate how RM could use Microsoft's product to deliver a solution "of defensible pedagogic value" (direct quote), as part of the next generation of collaborative learning systems. Now I should stress that this was a prototype (not a product) - we were mainly trying to get people thinking about such tools in the education context, so we built an education game for spelling, languages and maths.
The concept was quite simple; you get a few students around the Surface, and they have to work as a team to correctly spell the word (from the cue), assemble the phrase, etc - from the available tiles. The tiles are all around the Surface, and the team most co-operate to do well.
(caveat: it makes more sense if you can also see the people interacting with the tiles; for BETT, on overhead video was rigged with a big screen to display the users too).
And everything needs a name, we covered a fair amount of wall space with nominations - but please welcome Finguistics (which was my sole offering, in a rare moment of lucidity - I suggested the team's Surface as the naming prize, but they didn't go for it).
The geek stuff
This is a technology blog, after all ;-p
Note that for many reasons, this isn't intended as a "how to" - purely to whet your appetite.
From a development angle, the most important thing is: how do you write code for it? The good news is that you can use standard development tools such as Visual Studio 2008 and C#, with the regular .NET framework (including WPF) - or if you prefer, you can (I believe) use XNA. This means you have full access to the other .NET framework features, so you aren't struggling for building blocks (we used WPF, Entity Framework, LINQ, ADO.NET Data Services, etc).
Don't try this at home
The SDK for Surface includes a simulator to let you develop and debug easily; in particular, for simulating the different types of (concurrent) contact with the device. This works surprisingly well, although for best results you need a few mice (which feels odd at first, but you soon get used to it). Deployment to the real Surface was a breeze too, but this is where you quickly see differences. Not through any fault of the simulator: simply, things look and feel different when they are on a large horizontal screen than they do on a small(er) vertical screen. There were a few minor behavioural differences too (nothing substantial).
So IMO, Microsoft are quite sensible in restricting the SDK to people with a Surface; applications that work well in the simulator may be unusable in the Surface. There is also a strong temptation on a screen to think in terms of "up". There is no "up" on a horizontal screen that you can walk around, and an app that works well on a monitor is not necessarily going to make best use of Surface's unique features.
So even if you do somehow snag the SDK, don't be fooled that you are now the worlds greatest Surface developer: without a physical device to play with, you're fooling yourself.
Surface highlights
- Shiny... a very cool piece of hardware; the youtube (etc) videos fail to do it justice - you have to play with it to get a feel for how it responds.
- Clever detection : of fingers, "blobs", special markers, or even shapes etc (more complex) - very powerful
- Flexible : some of the sample apps simple throw things out on a scatter-panel, but one of the Microsoft team managed to write a replacement layout engine to provide full physics; this made the whole thing feel much more "real"
- Styled : by drawing on the WPF goodness (not to mention Dave "Glossy" Crawford's input, and help from Infusion), it was possible to get a pretty impressive app working (with iterative GUI progression) very quickly
- (more notes on the unique advantages of Surface can be found on the Microsoft site, or RM's version here)
Other learning points
I come away with more than just memories of Surface:
- In the past I've mainly been involved with LINQ-to-SQL (due to timing, complexity, etc). This was my first production use of Entity Framework, and it worked OK. I'm still a little wary of how much might change between now and vNext of EF, but the tool itself worked fine and got the job done, which is what is important to me.
- I've had little production use of WPF, so the whole xaml/designer/developer workflow was new to me; and again, it worked. We had some first-rate designers working in Blend, throwing us xaml for Visual Studio; it all worked very smoothly.
- It was also simply a really enjoyable time working with some Microsoft / external experts - very informative and productive
Anyway - it was a great gig. If you happen to be near BETT over the next few days, check it out (there are 2 devices on-site). A big thanks to everyone involved, especially Microsoft who make great hosts, and my boss (for letting me disappear).