BT

Rapid Application Development using Naked Objects for .NET

Posted by Richard Pawson on Dec 23, 2008 |

Naked Objects for .NET is a framework that provides an implementation of the naked objects architectural pattern for the .NET framework. The basic concept behind naked objects is that, when writing a business application, the only thing you should write are the domain objects and the business logic should be encapsulated in those domain objects. A framework then exposes the domain objects to the user in the form of a rich object-oriented style of user interface, and also takes care of the persistence and management of those objects, typically via an ORM. This pattern is likely to appeal most strongly to those who subscribe to the idea of domain-driven design. Apart from eliminating the need to write a user interface layer and data access layer, the naked objects pattern also facilitates good object modelling - because you can instantly turn a prototype domain model into an application that can be evaluated by business users.

Most people’s reaction when they hear this is that it can’t possibly work for large-scale, complex business applications. Yet more than 1000 officers of the DSFA, a Department of the Irish Government, use applications written for Naked Objects to support the administration of social welfare benefits worth billions of euro annually.

History

The Naked Objects framework started its life on the Java platform. The earliest versions were written in Java 1.1. In what has to be one of the greatest flukes in the history of software development, we discovered that it would run, unmodified, on the .NET platform as J#. However, as later versions of Naked Objects migrated to Java 1.5 the .NET capability was lost. The final stroke was in January 2007 when Microsoft confirmed that J# would not be supported from .NET 3.5 onwards.

To address this, Naked Objects for .NET was created as a complete reimplementation of the framework. Written in C#, it is designed to take full advantage of the .NET platform capabilities including generics and LINQ. The generic user interface created by Naked Objects for .NET is written in WPF.

How Naked Objects works

This generic user interface does not rely on code-generation: it is created dynamically. At run-time, the framework uses reflection in order to render your domain objects on the user interface. This technique, known as introspection, is what allows developers to quickly go from domain model to usable application. This screenshot shows an open view of an object, which itself contains links to several associated objects (each icon represents a domain object); the user may navigate to those associated objects just by clicking:

(All the screenshots and code samples shown in this article are taken from a simple Expenses Processing application, which is included as part of the Naked Objects download.)

There are, of course, many frameworks that can render a domain object model in the form of a simple CRUD user interface, suitable for database browsing or maintenance. What makes Naked Objects more interesting is that it can produce a fully-functional application. By default, any public method will be made available to the user in the form of an action on a pop-up menu on the object’s icon, with the method name reformatted as the action name:

If the method has parameters method signature is used to create a dialog box for invoking the action, so:

public IExpenseItem CopyAnExistingExpenseItem( IExpenseItem otherItem)

Is rendered as:

The Other Item field requires the user to drag or paste in an existing object of type IExpenseItem (the UI field will reject an object of any other type). To the right of field there is also a drop-down indicator, which automatically provides a list objects of that type that are currently visible to the user on other tabs – which avoids needless switching between tabs.

How does the user find an Expense Item that isn’t on the screen or in that drop-down list, or, for that matter, create a new object instance when they don’t have another object to start from? This is where Repositories and Factories come in - standard patterns in domain-driven design. In Naked Objects terms, Repository and Factory are both just examples of services, services are just first-class domain objects in their own right. You can make use of services in three ways, though.

First, the services provide the main menu rendered at the top of the screen . Typically these provide actions that are the start points for business activities, such as creating a new Customer, or finding an existing one. Secondly, services can be injected into any other domain object that needs them, following the dependency injection(DI) pattern. Naked Objects manages this transparently - all you need to do is provide a set-able property of the type of the service required - there is no need for external configuration as required by many DI frameworks.

The third use of services is for what we term ‘contributed actions’. If a service has a public method:

public virtual IList <RecordedAction>
	allRecordedActions(IRecordedActionContext context)

Then this will automatically be contributed as a user action to any object that implements IRecordedActionContext, with the first field of the dialog automatically filled with the object you selected the action on. (This action appears within the ‘Recorded Actions’ sub-menu shown on the first screenshot - that being the name of the service that provides the action).

This powerful capability gives you way to achieve a kind of multiple-inheritance - at least from a user perspective. It has some conceptual similarity to the concept of mix-ins or to .NET extension methods, though the implementation is somewhat different.

Implementing business rules

So how would you implement business rules? There are two approaches. The first is through the use of attributes, which may be applied at the level of classes, properties, methods or parameters. For example:

  • By default, the framework requires the user to complete all fields before being able to save an object and to provide all fields in a dialogue before being able to execute an action. You may use an [Optionally()] attribute to override that behaviour.
  • [MaxLength()], [Mask()], and [RegEx()] allow you to specify constraints on input strings and/or to format them.
  • If you have a property or method that must be public for programmatic reasons but which is not relevant to the user, then it may be [Hidden]. Various conditions may also be applied to this attribute.
  • By default, the names of classes, properties and actions will be used, with some friendly reformatting, in the user interface - which we consider to be good practice. However, if you need a label that can’t be used in the code (because it contains symbols or punctuation, for example), then the [Named()] attribute may be used. (Note that there is an entirely separate mechanism to provide internationalisation of all the labels).

The second approach, which offers far more flexibility, uses programming by convention as illustrated below:

public virtual void CopyFrom(IExpenseItem otherItem) {...}
public virtual string ValidateCopyFrom(IExpenseItem otherItem) {...}

In this example, the CopyFrom method will be rendered by the framework as a user action; the framework will also recognised the ValidateCopyFrom method as providing logic for validating the parameters of the action: if this method returns a non-null string then the ‘OK’ button on the dialog box will be greyed-out and the string message made available to the user as a tool-tip. Similarly, DisableCopyFrom would provide logic for making the action unusable , for example when a claim has already been persisted. (Note that the framework has an entirely separate mechanism for managing permissions based on a user’s roles). There are several other such conventions, for example to specify default values or specific choices (drop-down lists) for parameters.

POCOs

These coding conventions add optional behaviour. There are just three simple coding conventions that you must follow. Two apply to properties as shown here:

public virtual Employee Claimant {

    get {

        Resolve(employee);

        return employee;

    }

 

    set {

        employee = value;

        ObjectChanged();

    }

}

The Resolve() call ensures that the object has already been loaded into memory, and the ObjectChanged()notifies the framework that a property value may have changed - both in order to update any views of that object, and to ensure that the change is persisted. (Note that the framework handles this persistence for you automatically: you do not write any methods for loading, saving or updating objects).

The third requirement is that any object that you create programmatically is notified to the framework: instead of writing:

Employee employee = new Employee();

You need to write:

Employee employee = Container.NewTransientInstance< Employee>();

These calls are not made to the Naked Objects framework though, they just delegate to methods defined on an IDomainObjectContainer. If you provide a property of this type on your object, the framework will inject a container that implements these functions for you at runtime. As a short-cut, you have the option to make your domain objects inherit, ultimately, from AbstractDomainObject, which will save you a few lines of code in each case.

But it is important to stress that this inheritance is optional: Naked Objects is a POCO based approach. Apart from POCO being a good thing in general, it means that you have the option to take the same domain objects and run them in a more conventional architecture: writing a custom user interface and other layers as required. All you’d have to do is stub-out those three types of call to the Container. (If you are willing to use Aspect Oriented Programming, then you could get rid of the Resolve(), ObjectChanged()and newTransientInstance() calls from your domain code altogether - but we did not want to tie Naked Objects specifically to an AOP implementation.)

The attraction of this is that you could simply use Naked Objects to support the Domain-Driven Design parts of the process: you wouldn’t be forced to implement the system on Naked Objects. And the good news is that all you then need is the Express Edition of Naked Objects, which is a free download.

Hello stranger!

You need to Register an InfoQ account or to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

What is the this, an infomercial? by Robin Clowers

Naked objects has recieved some pretty heavy criticims, and this was not mentioned at all...

There is a huge usability problem with this type of application; not to say it can't work, but people will have to change the way they work to fit the software, rather than the other way around.

Take a look at this article: The Emperor Has No Clothes: Naked Objects Meet the Interface.

Awesome! by John DeHope

I am fascinated by naked objects. I had seen the Java implementation before, but I am a CLR kind of guy. Thanks for bringing this to my attention. I think the world is ready for a programming environment that is one level ob abstraction higher than bare C#, and this is an example of that.

Re: What is the this, an infomercial? by Jonathan Allen

They didn't pay for it, and if I thought it was complete nonsense I would not have published it, but this is written largely by someone who works on the project.

This is the same deal we use for many of the technologies we want to introduce. If we get a lot of positive feedback on the article, then we will write more traditional news pieces on it. If not, then I'll drop it from our watch list.

Re: What is the this, an infomercial? by Javier Paniza


There is a huge usability problem with this type of application; not to say it can't work,

Then the solution is adding usability to this approach instead of reject it.
Maybe if we drop (or refine) the point 2 of Naked Object principle we can achieve usability. In other words, what if the UI is not a direct representation of the domain objects, but we can refine the presentation using annotation and a controller layer?

Look at this java.net article about automatic UI generation.

Time to update your evaluation, I suggest by Richard Pawson

Robin

Larry Constantine wrote that article in 2002 - based on Naked Objects 1.0 (the Java version is now on 4.0). His arguments were (mostly) wrong then; they are simply irrelevant now.

You need to understand that, strangely, Larry has always hated the general concept of object-oriented user interfaces (ignoring all the research showing their usuabiliy advantages). Easier to understand is that he has always hated the concept of auto-generated user interfaces. Naked Objects combines both ideas - a double whammy!

Your statement that "people will have to change the way they work to fit the software, rather than the other way around" is, I'm afraid, very naive. All software forces people to change the way they work, by definition. Plenty of research shows that there is no such thing as an intuitive UI. There is only familiarity. To a user that has been force-fed Windows Forms or web-based applications for years(which typically have shocking usability) then, granted, Naked Objects will be unfamiliar, and training is required. But, as we have always said Naked Objects is suited to 'sovereign' and not 'transient' applications (Alan Cooper's terms) - and the former always require some learning, because of their inherent sophistication.

What frustrates me most when people assert that Naked Objects is forcing something onto users for the convenience of software developers, is that they are ignorant of the roots of Naked Objects. It did not grow out of an attempt to improve software productivity and agility (though that is certainly a benefit), but rather from my own research into how to design systems that were more 'expressive' to the user (treated the user as a problem-solver not a process-follower). If you are not familiar with this, I would urge you to watch this video, which was recorded in 2001: www.nakedobjects.net/demo/demo_intro.shtml#expr...

It might just change your perspective.

Incidentally, my challenge to Larry at the time of his tirade was this: how come I can't find the word 'empowerment' (or any synonym thereof) in the index of any of his books, or any book about usability (and I have many).

Partly why we get this reaction from the usability community is, I believe, that we have touched a raw nerve. To use a biblical metaphor: 'they have choked on a gnat, but swallowed a camel'.

Richard Pawson

Customisation of the UI by Richard Pawson

In every project we've done using Naked Objects, the customer has started out wanting assurances that it would be possible to create a custom GUI on top of Naked Objects if they needed it. We have always said: the domain objects you come up with are not tied to Naked Objects - if you want to build a custom GUI then it's no more wortk (less in fact) than for a conventional system.

Hardly anyone, in fact, starts out believing that the generic user interface provided by Naked Objects would be acceptable for a delivered application - but they can see its power as a tool for capturing business requirements in the form of a usable domain model. What surprises them is that in certain cases not only is the generic Naked Objects user interface quite acceptable for a real business application - it is actually very good - because once a user has learned the basic forms of interaction, the modeless style of operation is very empowering. One important caveat: the generic UI is suitable only for sovereign applications - not for transient applications such as a publicly-accessed systems (where you do need a custom, scripted UI).

Is it possible to implement a workflow system by chen jianwu

I think the idea of Naked Object is good for most of the CRUD functions and straight forward operation for a typical application. It can really save a lot of repeated UI work for different domain objects.

But when come to more complex business logic, it will have difficulties. For example, in a work flow system, the workflow will have many states, the available actions are determined by actor, the state and the context, the internal state transition may also be complex. Is it possible to support this kind of application.

Re: What is the this, an infomercial? by David Rozenberg

What are you afraid of? You accept the existence of the frameworks because they save a lot of your time when developing applications. Here is another way to save your time and not to develop what can be used without any extra programming. The article you quoted cannot be taken serously because it was written long ago and the only point was that using the Naked Objects takes away some portion of your pie. I think that what is done by Richard Pawson and his team is a serous push to rethink what you really need to do as the programmer and what can be re-used without you spending hours and hours on creating another set of screens.

Re: Is it possible to implement a workflow system by David Rozenberg

I think you are missing the point. You simply need to have necessary set of business objects which can be examined at the right spots of your business process. Look at this from the standpoint of how you debug any application creating breakpoints and examining the content of the objects at those.

Re: Time to update your evaluation, I suggest by David Rozenberg

What Richard did not mention, but you need realize that with this appoach (Naked Objects) you can forget about spending hours on GUI generators and writing event handlers and dedicate your time to solving your business problems. If you are not happy with such perspective, I think your manager will be. If you want to spend most of your career on developing nitty-gritties instead, that's your choice.

Re: Is it possible to implement a workflow system by Richard Pawson

I'm not a fan of worlflow as a concept (see my blog article: Workflow: A triumph of hope over experience).

Nonetheless, let me make it clear that Naked Objects can support very complex business logic. It is perfectly possible for a domain object to have a status, for the logic of those status-transitions to be complex, and for the actions available to the user to depend upon the status of the object. (This is done, dynamically, by means of HideXxx and/or DisableXxx methods, where Xxx is the corresponding action.

The actions available may also be determined by the actor (or, more specifically, by the role(s) that the actor has). This is administered outside the system as is usual.

Licensing by Mark N

Why does the .Net version have Express and Enterprise versions and the Java version is open source?

Re: Licensing by Richard Pawson

There are several different ways of attempting to balance the desire to make your stuff as widely accessible as possible, and the need to earn a living. This is the way we have chosen - at least for the time being. The free Express Edition means that anyone can use Naked Objects for .NET to build prototypes (or to create domain models for deployment on a more conventional platform). Those who see the benefit in using Naked Objects as an enterprise deployment architecture (for which they will need the Enterprise Edition) do not generally have a problem with paying for that.

Richard.

Re: Licensing by Mark N

@Richard - I definitely was not questioning the need to make a living. I guess I was wondering why .Net was licensed one way and Java another. I know that at one time the Java version was not opensource (or was GPL). It seems the Java one is being advanced so .. ? Just curious [as always] before i jump in.

business apps currently in version 6.2 in PHP land... by Richard Kucera

Re: Licensing by Dan Haywood

Hi Mark,
Speaking as one of the main contributors to the Java version, the reason that the Java license is open source (Apache License v2) is that in Java-land it's just not realistic to charge for this kind of software. After all, one can get complete J2EE app servers for zero dollars. The .NET marketplace is different; it's defined by Microsoft who as we know absolutely aren't in the game of giving away their software.
Dan

Re: Licensing by Mark N

Thanks Dan, that is what I hoped/figured I would hear. It seems the Java version is under active development and doesn't seem to be suffering due to it being open source. :)

Re: Licensing by Dan Haywood

Mark,
Absolutely, the Java version is under active development! Like the .NET version, the new version 4.0 has had some serious reworking. It still supports the original two viewers, but there is also a sister project, scimpi, which Rob Matthews is working on, that provides a customisable web UI. I've also been working on sister projects to provide an Eclipse RCP viewer and a RESTful webservice, as well as an updated JPA-based object store. These won't be part of NOF 4.0 but I'll be carrying on working on them throughout this year.
You might also be interested to know that hopefully next month my forthcoming book ("Domain Driven Design using Naked Objects", Pragmatic Bookshelf) will go into beta PDF form. It's being written against NOF 4.0 so is bang up-to-date.
Cheers
Dan

Re: Time to update your evaluation, I suggest by Niall Barry

I agree with Richard and feel that I should add the following:

True Domain-Driven Design, as I understand it, by definition actually reflects the way that people work. The struggle in the enterprise is developing and maintaining the basic understanding of DDD. Once that's there to any significant degree, then the Naked Objects approach, in my experience, is a brilliant way of implementing that idea. The generation of the user interface serves two major purposes in that it allows us to focus on the business logic (a major saving in many ways) and its user interface, far from being an obstacle, actually helps to focus on/re-inforce the ubiquituous language that is the essential (for me) part of DDD. Once the initial unfamiliarity (caused to some degree by deficiencies in more traditional approaches) is over, there is very widespread acceptance of the UI.

Re: Licensing by Mark N

I will put the book on my list to get. :) I have a BIG list.

I had forgotten there was an Eclipse RCP UI. I re-ran across that last night.

Thx for the heads up on scimpi. Googled it and added it to Delicious.

I thought by now i would have a few projects using NO especially after it change the Java license to Apache. But as usual, things never go as planned. As i have said elsewhere, I have been following NO for years (6+ at least).

Re: Licensing by Mark N

I meant to also add that the WPF ui looks pretty good.

Re: Time to update your evaluation, I suggest by Dan Haywood

Niall omitted to say that he is the IT Director/CIO for the DSFA. So he knows of what he speaks...

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

22 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2013 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT