# Sunday, August 24, 2008

There are currently two approaches when using L2S. Either adding attributes to classes to denote columns, or creating an external XML mapping definition. Neither of these is great. Attributes mix non domain concerns, namely database schema, into domain objects. XML mapping needs to be kept in sync with the classes it describes. During the early stages of a new project, the structure of classes can vary and morph over time. So manual mapping is annoying.

My suggestion is to create a "convention-based" mapping. Where you can define POCOs and then have reflection to build the mapping, based on some simple naming conventions. This mapping can then be used by a DataContext and a database created from it. (Note that I am only considering green field developments, where we are working "code-first".)

The conventions I have thought about so far include:

  • A property named "Id" will be the primary key.
  • If Id is an int then make it auto incrementing.
  • All primitive, string and DateTime properties are columns.
  • All properties having the type of another entity in the DataContext are associations.
  • All properties of type EntityRef<T> are associations.
  • There must be a foreign key Id property defined for associations.
  • Any property with subtype a of IList<T> is an association.

One-to-many associations need to be a bit smart with their names. Consider:

class Customer {
  public Employee ReferringEmployee { get; set; }
}
class Employee {
  public List<Customer> ReferredCustomers { get; set; }
}

The mapping needs to understand the "ing" and "ed" relation. Also, we'll perhaps need support for TechSupportEmployee <--> TechSupportedCustomers.

The conventions should follow the usual rules of English grammar. I hope, therefore, that they do not interfere with the universal language discovered by domain driven design.

As a project begins to settle down, there will be requirements that the convention mapping doesn't support. Rather than having to switch to full manual XML mapping, perhaps an augmentation layer could applied. This could describe specific cases of the mapping that are different. For example, a certain primary key column using GUIDs instead of integers.

c# | linq | linq-to-sql | orm
Sunday, August 24, 2008 11:09:43 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 23, 2008

I decided to spend the day creating Spectacle.

Spectacle is a spec-driven/bdd/{buzzword-of-choice} embedded DSL for Nemerle. It creates NUnit compatible test fixtures from very human readable code.

So in the spirit of release early, etc...
Project site: http://www.assembla.com/wiki/show/spectacle
Also: 3 minute screencast:
http://screencast.com/t/4dPdsg35Uj
You'll probably be needing to the pause to read stuff!
Enjoy :) all feedback is welcome.

An example spec:

spec "Account with 100"
    account = Account(100)

    getting account.Balance returns 100

    doing account.Deposit(100) means
        account.Balance == 200

    doing account.Withdraw(50) means
        account.Balance == 50

    doing account.Withdraw(200) throws ArgumentException

Wednesday, July 23, 2008 5:41:23 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
# Sunday, July 13, 2008

Sending data from a resource to a view in a strongly-typed, but syntactically lightweight manner is not possible with C# or VB.NET.

So check out this screencast of the new "render" macro in NRest!

In a nutshell, my resource looks like:

[Resource("")]
public class RootResource
{
    public Get() : void
    {
        def test = 42;
        render (Foo = "Hello", Bar = "World", test);
    }
}

My VB.NET view looks like:

Public Class RootPage
    Inherits Page(Of RootPageContent)

    Public Overrides Function GetHtml() As XElement
        Return _
        <html>
            <body><%= Content.Foo %>, <%= Content.Bar %></body>
        </html>
    End Function
End Class

The RootPageContent DTO class is generated at compile time by the render macro. Everything is strongly-typed.

.net | dsl | macro | nemerle | nrest | REST | web
Sunday, July 13, 2008 3:27:17 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 02, 2008

This is a very quick video showing the work I've been doing with Nemerle, ASP.NET routing and VB 9 XML literals.
I'm trying to find the most efficient way to create RESTful web applications. I'm willing to use all the tools in the box and even make my own to achieve this.

.net | nemerle | REST | screencast | vb.net
Wednesday, July 02, 2008 11:19:24 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, June 24, 2008

When unit testing a class that relies on app settings you don't want to be setting up web.config to get it running. I realised today that app settings are a dependency of a class. Therefore they must be injected by the IoC container. I'm using Ninject...

I have this in my web.config:
<appSettings> <add key="bar" value="1234" /> </appSettings>

I want to inject that value into a class constructor as below:

class Foo {
  public Foo(AppSetting bar)
  { ... }
}

AppSetting is a simple wrapper around a string:
class AppSetting {
  public AppSetting(string value) { Value = value; }
  public string Value { get; private set; }
}

I then configure Ninject with:
Bind<AppSetting>().ToProvider<AppSettingProvider>();

Where AppSettingProvider is:
class AppSettingProvider : Ninject.Core.Creation.IProvider
{
    public object Create(Ninject.Core.Activation.IContext context)
    {
        return new AppSetting(WebConfigurationManager.AppSettings[context.Target.Name]);
    }

    public Type GetImplementationType(Ninject.Core.Activation.IContext context)
    {
        return typeof(AppSetting);
    }

    public bool IsCompatibleWith(Ninject.Core.Activation.IContext context)
    {
        return WebConfigurationManager.AppSettings[context.Target.Name] != null;
    }

    public Type Prototype
    {
        get { return typeof(AppSetting); }
    }
}

The end result is a class that can be trivially unit tested, since it never calls the configuration API directly. Also, there was no need to create some complex abstraction around the API just to enable unit testing. In the future I can even change how and where app settings are stored (maybe using a database for example) all I'd have to do is make a new provider.

Ninject - in a word: awesome!

Tuesday, June 24, 2008 12:13:21 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, May 10, 2008

A demo website using my Hasic view engine for ASP.NET MVC.

HasicDemo.zip (275.95 KB)

.net | vb.net | web | hasic
Saturday, May 10, 2008 5:37:41 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, April 29, 2008

I have started using Ninject a dependency injection framework for .NET. I find it very easy to use and recommend that people take a look.

Something in particular that I found useful is the ability to bind open generic types.

class Program
{
    static void Main(string[] args)
    {
        var k = new StandardKernel(new MyModule());

        var di = k.Get<Data<int>>();
        di.Content = 14;
        Console.WriteLine(di.Content);

        var ds = k.Get<Data<string>>();
        ds.Content = "hello";
        Console.WriteLine(ds.Content);
    }
}

class MyModule : StandardModule
{
    public override void Load()
    {
        Bind(typeof(IData<>)).To(typeof(Data<>));
    }
}

class Data<T> : IData<T>
{
    public T Content { get; set; }
}

interface IData<T>
{
    T Content { get; set; }
}

Very cool!

.net | c# | ninject | programming
Tuesday, April 29, 2008 7:36:59 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
# Monday, March 24, 2008

After beginning to use Snooze on a real project I realised it needed to be more extensible and more testable. So I re-wrote it!

The new code is now in the trunk: http://svn2.assembla.com/svn/snooze/trunk

A key extensibility point is the "ResourceContext" class. Before a resource is invoked, it's ResourceContext is initialised with relevant data such as HttpContext, invoke verb, GET view and file type. The base Resource class allows sub-classes to specify a particular ResourceContext sub-class, by the use of a generic type parameter. So when using Snooze in a web project it is easy to define extra context data that is always available to any resources. Instead of adding properties to a Resource class, the use of a context object allows data to be easily shared between a sub-resource and it's parent resource chain.

A Snooze resource also has a ResourceFactory object. The type of this is also generically typed so that a web project can provide a customized factory.

These changes make it easy to do things like test that a resource creates sub-resources (through the factory).

Monday, March 24, 2008 5:19:52 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 

I've seen people testing that RenderView is called by a controller by inheriting into a "testable" controller. Madness!

RenderView is just a convenience method that calls to IViewEngine, so why not just test expectations on that with a mock? We basically want to test that the correct ViewContext is sent to the RenderView method of the view engine.

This is my test:

[TestFixture]
public class HomeControllerTests : ControllerTestsBase<HomeController>
{
    public override HomeController CreateController()
    {
        return new HomeController();
    }

    [Test]
    public void Renders_Index()
    {
        var render = ExpectRenderView();

        Controller.Index();

        Assert.That(render.Data.ViewName, Is.EqualTo("Index"));
    }
}

I don't think we can get more straight forward than that!

This is my test base class:
(I'm using Moq as the mock framework.)

public abstract class ControllerTestsBase<T>
    where T : Controller
{
    public T Controller;
    public Mock<IViewEngine> ViewEngine;

    [SetUp]
    public virtual void SetUp()
    {
        Controller = CreateController();
        ViewEngine = new Mock<IViewEngine>();
        Controller.ViewEngine = ViewEngine.Object;

        Controller.ControllerContext = new Mock<ControllerContext>(new Mock<HttpContextBase>().Object, new RouteData(), Controller).Object;
    }

    public abstract T CreateController();

    public RenderCall<ViewContext> ExpectRenderView()
    {
        var render = new RenderCall<ViewContext>();
        ViewEngine.Expect(v => v.RenderView(It.IsAny<ViewContext>()))
            .Callback(new Action<ViewContext>(render.Set));
        return render;
    }
}

The RenderCall class provides a place to receive the view context that is passed.

public class RenderCall<T>
{
    bool _called;
    T _data;

    public T Data
    {
        get
        {
            if (!_called) throw new InvalidOperationException("View was not rendered.");
            return _data;
        }
    }

    public void Set(T data)
    {
        _data = data;
        _called = true;
    }
}

.net | mvc | thinking | web
Monday, March 24, 2008 4:08:16 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, February 19, 2008

VB.NET 9 introduces a clean syntax for expressing XML data. XHTML is XML so why not use VB.NET to generate it, instead of ASPX pages? People are creating view engines for the new ASP.NET MVC framework. How about a view engine that uses VB.NET XML literals?

The benefits to this approach include full intellisense and access to a the full VB.NET language when creating HTML.

I see a view as a function from some data to an XML element (the <html> element):

Function CustomersPage(ByVal title As String, ByVal customers As IEnumerable(Of Customer)) As XElement
    Return _
        <html>
            <head>
                <title><%= title %></title>
            </head>
            <body>
            <%= From customer In customers Select _
                <div id=<%= customer.LastName %>>
                    <h1><%= customer.FirstName %></h1>
                </div> %>
            </body>
        </html>
End Function

The important change from ASPX is that this is HTML in Code, rather than Code in HTML. As a result less "automagical" behaviour is required; It's just a function! This means AJAX features like "partial rendering", where a section of page needs to be updated, can be expressed by just calling a function that returns a <div> element. That same function can be used by the full HTML page function too.

ASPX "usercontrols" become simply functions as well. ASPX Master Pages are functions that have arguments for "placeholders" that get inserted into an template HTML page. Instead of having to reinvent a bunch of programming language concepts inside ASPX, we can just use a programming language that now support XML!

The only down side to this approach is we lose the IDE visual designer support. However, I find viewing an ASPX page that contains even simple conditional data rendering next to useless. I'd rather keep IE open and just refresh the page to see changes.

I am yet to embrace the MVC framework. I am waiting to see if the next release can better support Snooze framework ideas. However, there's no reason I can't use this VB XML magic in Snooze as it current is.

.net | html | thinking | vb.net | web | xml
Tuesday, February 19, 2008 12:12:17 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |