No, NSK is not (about) Northwind

So it seems my pet project has been Ayende-ified; Oren has been so kind to let me have a preview at his posts and that urged me to talk a bit about what NSK is and what it is aimed for.

I started NSK in 2004 in order to have a “one size fits all” demo for the talks and classes I and my colleagues at Managed Designs were holding; all I wanted was a way to showcase topics such as:

  • How an O/RM works (Unit of Work, proxies, queries & fetch plan management, …)
  • How to implement common presentation design patterns (MVC, MVP, …)
  • How to unit test code

Other than having that demo, I also wanted to make everyone able to have it up & running as frictionless as possible, so I:

  • Made it open source (choosing IBM’s OSI-approved Common Public License) and downloadable from Sourgeforge
  • Had it use the “ubiquitous” Northwind database

I knew from the start that such a db would have impaired my ability to design an effective Domain Model, but I didn’t care ‘cause that was code that I was expected to show (and comment), and not targeted to the casual downloader.

Let’s just have an example: in order to allow me to explain how an O/RM works and avoid early adopters (remember, we are talking about year 2004/2005) fear for “O/RMs black magic”, I defined both a IUnitOfWork interface and my own query object, and then implemented both delegating the real work to NHibernate. I even implemented proxies for a couple of entities in order to show how O/RMs manage concurrency. Frankly, I did not pay much attention to my implementation of UoW/query object/proxies, because that implementation wasn’t neither expected to go live in a “production” system nor looked at as an advice to encapsulate an O/RM. That “poor man’s” O/RM, let me stress about that, was only meant to allow me to talk about how an O/RMs works without having to resort to NHibernate source, which IMHO would have been overkill. And when DLINQ Linq 2 SQL came to us, I renamed the IUnitOfWork interface to IDataContext in order to better adhere to .NET’s emerging jargon: again, I was only trying to have a “companion demo” which fitted my own presenting needs so, when the “pioneering era of O/RM” relating to the .NET community ended (which, IMHO, happened with Microsoft releasing L2SQL and then EF) I considered my “introduce O/RMs by explaining the inner workings” strategy obsolete, made a branch for those still interested in having a look to that code and had NSK switched to the LINQ side of the Force.

And then came the book (to which, BTW, both me and Dino refer to as “the brick” <g>): we needed a companion demo, and ultimately chose to use NSK so I had to fit into the codebase a bunch of samples covering nearly all the book’s topics, such as:

  • The book talks about IoC and unit testing, so I ended implementing custom factories for both ASP.NET MVC (which at the time was in the “v1 beta” timeframe) and WCF in order to inject dependencies and/or mock objects
  • the book talks about validation and we wanted to show the capabilities of Enterprise Library’s Validation Application Block (which I still think is pretty gorgeous), so I did put in demos using both the custom attributes and the xml rulesets to validate the domain model

Again, the codebase was intended to be looked at while being guided by the book and not as a fully fledged application (please note that NSK still does not sport a release) or as an example of how to implement a Domain Model. If you look to NSK this way, you will find a lot of thing you would do very differently in a “real” application. Just to make an example: you have a look at the CalculateTotalIncome() method of the Customer class and find the following, pretty sub-optimal, code:

   1: public virtual decimal CalculateTotalIncome()
   2: {
   3:     Contract.Ensures(Contract.Result<decimal>()>=0);
   4:  
   5:     decimal income = this.Orders.Sum(o => o.CalculatePrice());
   6:     return income;
   7: }

In a “real world” application, should the evaluation of the total income be a mere sum, I’d have the O/RM generating a proper query. But, for the sake of the project, I only wanted both a mockable customer repository and the above shown method in order to set up a unit testing demo for the following service:

   1: public virtual decimal CalculateSuggestedDiscountRate(string customerId)
   2: {
   3:     Contract.Requires<ArgumentNullException>(customerId != null, "customerId");
   4:     Contract.Requires<ArgumentException>(!string.IsNullOrWhiteSpace(customerId), "customerId");
   5:  
   6:     Customer customer = customerRepository.FindById(customerId);
   7:     decimal income = customer.CalculateTotalIncome();
   8:     decimal discount = 0;
   9:     if (income > 5000)
  10:     {
  11:         //Suggests a 6% discount if income>5000USD
  12:         discount = 0.06M;
  13:     }
  14:     else
  15:     {
  16:         //Suggests a 1% discount for every 1000USD of income
  17:         discount = income / 100000;
  18:     }
  19:     return discount;
  20: }

This way, I could write down the following test:

   1: [TestMethod]
   2: public void Test_Calculation_Of_Suggested_Discount_Rate_For_Customers_With_Total_Income_Of_Less_Than_5000_Dollars()
   3: {
   4:     decimal generatedIncome = 3500;
   5:     string customerId = "FAKE1";
   6:     var custMockBuilder = new Mock<Customer>();
   7:     custMockBuilder.Setup(c => c.CalculateTotalIncome()).Returns(generatedIncome);
   8:     var repoMockBuilder = new Mock<ICustomerRepository>();
   9:     repoMockBuilder.Setup(r => r.FindById(customerId)).Returns(custMockBuilder.Object);
  10:  
  11:     MarketingServices svc = new MarketingServices(repoMockBuilder.Object);
  12:     Assert.AreEqual<decimal>(0.035M, svc.CalculateSuggestedDiscountRate(customerId));
  13: }

To cut a long story short: the reader should look neither at the CalculateTotalIncome nor at the CalculateSuggestedDiscountRate service per se, but at the unit test. Think about it as a MSTest + Moq demo, and maybe you’ll get the picture I wanted to give to the reader. Being the code targeted at someone who has attended a class/talk or read the book, I thought there was no way to have someone misunderstanding the scope of the project.

The same goes for the domain model at large: if you take a look at it, you’ll notice that aggregates encapsulation is pretty low; I just managed to:

  • define an aggregate root abstraction (the IAggregateRoot interface), and built an eco-system aware of it (i.e. the repositories which uses IAggregateRoot explicit implementation and code contracts to enforce domain logic)
  • have the aggregate roots implement factories in order to prevent bad instantiation to happen (builder pattern anyone?)
  • encapsulate some navigation properties having the domain model “users” forced to use domain logic (i.e. the, AddProduct method of the Order entity which is the only way to add a product to the order… or avoiding that, from a domain logic perspective)
  • added a bunch of domain services (i.e.: GetRelatedProducts, CalculateSuggestedDiscountRate, …) in order to show the differences lying in implementing domain logic within the model and/or by means of services

Again, that was enough for my own needings; demo after demo, technology after technology (code contracts, entity framework POCO mapping, jquery, MVVM) NSK grew up and nearly became the “one size fits all” demo I needed in my talks. Up to late 2010/early 2011, I only managed to update NSK in order to remain useful for my own needings.

All of a sudden, though, “developing” NSK wasn’t fun anymore so I settled down and asked myself what I wanted to do with it; my answer was: “make it a real application under the form of an Amazon-like e-commerce web site”. That would have justified the complexity DDD kicks in and also (hopefully) make the project a foundation for solutions we build at Managed Designs. I opted to go for the CQRS way and started focusing of the front-end: so I quickly implemented a read model and started implementing a couple of user stories only to define a structure for the project (architecture, file system, NuGet-based pre build actions, …), only to discover that such a project is too much of an effort for a single person which is going to develop it in his spare time, so I contacted a bunch of friends in order to ask for their support. Then we stopped committing code and started writing down the user stories that will lead our effort from now on.

That’s why the read model and the domain model appear so similar, being the former a mere database reverse engineering and the latter the model that fitted my own “demoing” needings, but we’ll remove this model (and other code, such as the repositories) as soon as we’ll have the new ones, which will emerge from the user stories. Remember that I *still* need demoes for my talks, so I won’t be able to remove “demoable” code until when I have a replacement for it. The nice part is that we think that the new model will be composed by “real” aggregates and that we’ll switch from SQL server to a NoSQL database, so the “R” and “C” parts are going to be pretty different.

At this very moment, being the “code writing” on a hiatus, the only code I would recommend a casual downloader to look at is the stack that shows the recommended projects onto the home page, which picks the products following the following strategy: “Given all products->Choose the ones we are selling (which, of course, aren’t all the products we have in the db)->Then select only the available ones->Let’s pick up the projection we need within this view”. That happens picking them (the products) by means of an expression tree that is composed while goin’ up the application stack: that’s an idiom we at Managed Designs nicknamed LET (which stands for Layered Expression Trees) and we think that it’s a pretty powerful idiomatic way to express logic in a DDD context. I’ll talk about it at the next local ALT.net event, and dedicate soon a blog post to it.

To sum it up: if you’re looking for a sample application, you’d better search for a project sporting a release version (which is something NSK still doesn’t) or, at least, wait for we to implement some more user stories in order to allow the whole design to consolidate. In the meantime, the project can still be looked at in order to take advantage of some “pills” you could be interested in for your projects, such as:

  • JQueryUI integration with ASP.NET MVC (i.e.: the DateTime partial view implemented for both WebFormsEngine and Razor engine)
  • MVC and WCF custom factories
  • NuGet-based pre build actions in order to easen you first “compile&run” (for those using the recently released v1.6 of NuGet, I’d recommend to have a look at the “package restore” feature)
  • Code Contracts aware IRepository interface (don’t focus on actual designs: the real meat lies in having IAggregateRoot + code contracts enforcing your validation even when application code “forgets” to do domain object validation)
  • Rss and Atom custom ActionResults for ASP.NET MVC, taking advantage of framework’s built-in serializers

That’s all code you can use (and refactor to satisfy your own needings) due to the license chosen. Enjoy NSK!

P.S.: I know, project’s description on Codeplex sucks bad. Mea culpa: I’ll fix it ASAP.

posted @ martedì 10 gennaio 2012 12.17

Print

Comments on this entry:

# re: No, NSK is not (about) Northwind

Left by Luca Minudel at 10/01/2012 13.51
Gravatar
The post from Ayende is based on wrong assumptions and some misunderstandings.
This is common between we developers, because communication skills are not our main strength and because sometime our ability with the code/machines make us arrogant with people...


Still someone for free spent time to look at the code and comment it.
While the conclusion are biased by the wrong assumptions and the misunderstandings, maybe some mentioned facts can be used to inspire some potential improvements. Let see if we can take something good out of it.


- You already pointed out the description, it can be improved to avoid misunderstanding, that are possible with the current description as the post of Ayende show.


- The other thing that could be improved is the number of projects: all those projects are released together so there are no need to split them in different project.
To define the logical grouping of classes, namespaces should be used.


- Not sure about the comments, usually they can take away the focus from the readability of the code. Maybe class/method/arguments names could be reviewed to check that they explain in an easy way what the code is doing. This is an hypothesis from me, don't know the code to say if this really apply.

P.S. in practice NSK SDK has proven to be useful to many people to start to look into architecture and is an example useful for the book you wrote. NSK SDK seems to be very useful , keep up with the good work guys !

# re: No, NSK is not (about) Northwind

Left by Maurizio Tammacco at 10/01/2012 14.08
Gravatar
Ayende's post is definitely the result of misunderstandings, but on one thing he's, however, absolutely right, or the implementation of ICollection by IRepository violates the contract and provide no implementation for some methods.
LSP and ISP should make you think.

# re: No, NSK is not (about) Northwind

Left by raffaeu at 10/01/2012 14.10
Gravatar
I started to follow this project in late 2006 and I still remember how much I struggled to learn that complicated architecture (Domain, DAL, BLL, UI).
After the first trial I moved back to NSK in 2007 with a new application and this time the effort was well spent; the customer I built that application for is still using it, so the architecture is not so overcomplicated and not understandable.
Then I moved to BM and Dino and Andrea published their book that I have exhaustively evangelized in the company I working now.
Our code base is very close to NSK and I (we) personally believe that this can be a succesfull and reusable architecture.
Of course you have to be *forward-looking*

# re: No, NSK is not (about) Northwind

Left by Danimar Ribeiro at 10/01/2012 18.22
Gravatar
I understand your point. But also Ayende is right.
When I first looked this example, I got really confused to understand, and I thought this example was completely right. But after reading some reviews from Ayende, somethings got cleared to me. He shows the wrong points, it doesn't matter if the intention wasn't supposed to be that, to the people who are starting this advice about what is right, and what's wrong is good.

# re: No, NSK is not (about) Northwind

Left by Nazareno at 10/01/2012 22.29
Gravatar
NSK is not an easy project. I start to “read” it some years ago and I found really difficult to understand it, but I never think that it was a problem of the project (or of its developers). My feeling was that I was not ready for it.
Some years after I have the possibility (and the luck) to study better the underling architectures and I start to understand how to “use it”. At the moment this is not a sample app that you can reuse “ready, steady, go” on you projects. I use it to search suggestion about design or implementation, knowing that I have to write my own code to use it in my solution.
It, also, try to investigate new topics (like CQRS) when there is no so much implementation reference project around. I think this is another good thing.
Even if I do not think that you can measure a solution using the number of project, the large number of project is due to the fact that this solution tries to embrace the most common frameworks/tools.
A real and complete implementation of a MES project (layered and with test project) made using lot of pattern inspired by this project count “only” 11 projects (obviously we have chosen only one ORM and one presentation design pattern).

# re: No, NSK is not (about) Northwind

Left by tobi at 11/01/2012 11.40
Gravatar
As long as the codebase contains stuff like this (ayende.com/.../image_thumb_7.png) the project is really an embarrassment.

No excuses for releasing obviously unreviewed code as sample code.

I actually have people in my company who do this. I wonder where they got this advice from?

# re: No, NSK is not (about) Northwind

Left by Daniel at 11/01/2012 13.28
Gravatar
I thought that demos and books are meant to present the *best* way to write an application, not some so-so, average way (I won't call names).

# re: No, NSK is not (about) Northwind

Left by Luca Minudel at 11/01/2012 14.26
Gravatar
@tobi @Daniel

the focus of the project is on the distribution of responsibilities and the collaboration between objects at the class levels.

the focus is not in the method implementation code.

what you pointed out can be improved indeed, that still does not change the value and the usefulness of the project. that's why in my opinion you are missing the key point in your comments.

since the project itself is an open-source project that is evolving, it is perfectly normal that at some point in time some part of the code is not perfect.

and again the main point to focus are the one related to the design (e.g. is DIP and OCP, does dependencies goes throw abstract types and intefaces, are dependencies injected into costructors, are singleton and static avoided, are methods implementation short and each class do just one thing well, are names of classes and methods and parameters clear and meaningful and easy to understand ?)


if you can point out design related issues and suggest improvements, those would be constructive and useful and very appreciated comments

# re: No, NSK is not (about) Northwind

Left by Jason Meckley at 11/01/2012 14.57
Gravatar
So the project has evolved over the years. What i'm reading between the lines is you have 1 general purpose project as opposed to many context/demo specific projects.

simply put, context specific projects will always be better as the reviewer doesn't need inherent knowledge about what was intended vs. what should be ignored.

not to mention there is some level of accountability with public code and publishing a book. whether you explicitly say it or not, it says "this is how you do it".

# re: No, NSK is not (about) Northwind

Left by Arnis Lapsa at 11/01/2012 15.19
Gravatar
Whatever purpose of app is, it surely reminds me "Enterprise fizz-buzz" project:

code.google.com/.../#svn%2Ftrunk%2Ftrunk

# re: No, NSK is not (about) Northwind

Left by trustee at 14/01/2012 0.14
Gravatar
please delete this project from internet. it does more harm than good

# re: No, NSK is not (about) Northwind

Left by Andrea Saltarello at 14/01/2012 0.27
Gravatar
@trustee: can you explain me why, please?

# re: No, NSK is not (about) Northwind

Left by Riccardo at 20/01/2012 11.41
Gravatar
Hi all, I read all posts from Ayende around NSK and also commented out some of them. It used some implementation optimization in order to justify his point of view. Is like if one say... I have an hole in my pants then I have to change all my dress. He is trying to communicate the concept that the repository abstraction is not useful. His blog code source, prove exactly the opposite :)

# re: No, NSK is not (about) Northwind

Left by haroon at 30/01/2012 20.22
Gravatar
I think Ayende needs to provide some good examples other than NSK to learn from instead of just critisizing.

# re: No, NSK is not (about) Northwind

Left by DalSoft at 29/02/2012 20.57
Gravatar
With the tagline on the project page: "The application has been designed using common patterns, such as the ones defined within the "classic" "Designs Patterns" by Erich Gamma et al. and "Pattern of Enterprise Application Architecture", by Martin Fowler; though not required, these lectures are strongly recommended." Why not change the project based on Ayende's reviews so it can be a good point of reference for devs? Why there is such passion about this is devs use projects and examples like this as best practice and it reflects on the whole .NET community.

Agree with the point about the code being from 2004 (what's acceptable does change) which is why I think an update would be a good idea.

# re: No, NSK is not (about) Northwind

Left by Bob at 21/04/2012 16.37
Gravatar
I have a problem with Ayende's comments because he doesn't give a better solution. He seems to advocate putting data access code in the presentation layer. That might be fine for Racoon Blog, but what about applications with a lot of business logic? Surely, he wouldn't advocate putting business logic in a controller for a large enterprise application?

# re: No, NSK is not (about) Northwind

Left by Jakub at 03/10/2013 14.10
Gravatar
Very interesting project. I'm not a specialist in this type of work, but i can see the advetages of your ways.

# re: No, NSK is not (about) Northwind

Left by undergraduate thesis at 08/01/2014 15.44
Gravatar
School people regularly gravel at whatever point they think about their proposition or are going to take a shot at it. This article offers proposal written work tips for both undergrad and graduate scholars with the trust of making the knowledge of picking and working with an examination supervisor/mentor a charming one.

# funy image

Left by funy image at 11/02/2014 10.20
Gravatar
The funny images have most important part in our lifes beacuse its keep our charmfull and our heart filled with pleasure so the funny images play a diffrent role in our life for fun.
funy image

# re: No, NSK is not (about) Northwind

Left by tensioner at 03/04/2014 11.00
Gravatar

# games provides

Left by bola at 03/04/2014 22.31
Gravatar
Amusements and entertainments are outstandingly discriminating for us. They keep us sound and fit. They offer us transform from the dreariness of commonplace life. It is a useful strategy for energy and physical development. Diversions and amusements help in character building. They accommodate us imperativeness and quality. Diversions and entertainments are techniques for mental and physical improvement. All around diversions, we come to take in various things. We evaluate http://gamingjail.com/
how to help mental conform betwixt trusts and dejection. They make us evaluate how to handle the testing condition. Diversions make an inclination of pleasantness. They make in us collaboration.

# NO NSk

Left by Stanford at 13/04/2014 0.00
Gravatar
I think so the author is right.. But can't pick up the Admin SO far.

# Retrieve Wifi Passwords using Android

Left by Robert at 13/04/2014 21.32
Gravatar
Ever lost or forgotten your Wifi Passwords? Don’t worry your mighty Android can help you in this regard too.. Yeah you heard it right,you can retrieve all logged in passwords using any Android phone.

# re: No, NSK is not (about) Northwind

Left by polo at 16/04/2014 4.50
Gravatar
The human heart damage, Moncler Jackets Outlet Online, caused by the rupture of a dream, Polo Outlet Online, while broken dreams later, Gucci Outlet, it will stand up, Michael Kors Outlet, Like the moon, Barbour Jackets Outlet Online, full moon and so came the moon, Coach Factory Online, the moon looked forward to, Woolrich Outlet Online, the full moon, North Clearance, however, Coach Outlet Online, the dream is so fleeting, Pas Cher Longchamp Sacs, and even its light is so blurred, Beats By Dre Outlet, in blurred, North Face Jackets Outlet, and take a look at the wind gracefully floating past, that there are my family, Ralph Lauren UK, with my free pleasure, Burberry Outlet, one day, Moncler Jackets Outlet, lightly, Canada Goose Outlet, in the past, a mirror, Ugg Boots, according to himself, MCM Backpack Outlet, but nowhere to escape, Cheap Hollister UK Online, a voice sounded from a distance, Michael Kors Outlet Online, to the sun to dry yourself, Michael Kors Purses, well, Monster Headphones Outlet Online, time is so elegant, Polo Lauren Ralph, like a familiar face.

Gucci Outlet Online, http://www.guccishoes-factorys.net/

# Free SEO Services

Left by Sobia Rani at 30/06/2014 21.35
Gravatar
Most Microsoft Office workstation clients learn Word or Excel in the first place, generally Outlook eventually and perhaps Powerpoint later. Be that as it may Access is the particular case that has a tendency to be adapted last. Why is this? http://pakseosecrets.blogspot.com/
Numerous MS Office clients as of now have admittance introduced on their workstations however the application can regularly sit there unused, simply holding up to be propelled.

#  7 Pato Voetbalshirts -Korting en hete verkoop Barcelona voetbalshirts kids

Left by 7 Pato Voetbalshirts at 22/10/2014 14.00
Gravatar
Een goede gezondheid is erg belangrijk 7 Pato Voetbalshirts voor iedereen, vooral kinderen, zoals bijna elke ouder zal een sport kiezen en spelen met hun kind. En voetbal moet de eerste keuze zijn. Dus als je kinderen die alleen kopen voetbal goedkope voetbalshirts en spelen met hen om uw geluk te delen.

Laat me je iets vertellen over een sterke Isco 23 Voetbalshirts voetbalclub Barcelona, vertellen de laatste Champions League groep F eerste drie races begon, Barcelona thuis 3-1 nederlaag van Ajax. Neymar opende de scoren van de opening van zeven minuten, Messi massa schieten verdienstelijke daden, 69 Champions League-goals bond de C Lo.

Dus we kunnen meer en meer mensen zoals ze te zien en ze zullen kopen Bale 11 Voetbalshirts ook een voetbalshirt kinderen om hen te ondersteunen. De blauwe en rode kleuren van het shirt eerst gedragen in een wedstrijd tegen Hispania 1900 Verschillende concurrerende theorieën zijn naar voren gebracht voor de blauwe en rode ontwerp van het shirt van Barcelona.

Nu worden ze vervangen door Qatar Airways voor het seizoen 13-14, de deal zorgt voor een commerciële sponsor logo aan de liefdadigheid logo, twee jaar in zes-jarig contract te vervangen.

We kunnen hun 2013-14 seizoen voetbal jersey is erg mooi, vinden? Waarom geen bezoek aan onze online website http://www.voetbalshirt2015.com kopen dan voetbal speel je met je kinderen. Ik wed dat het zal het beste cadeau zijn.

Your comment:



 (will not be displayed)


 
 
 
Please add 5 and 8 and type the answer here:
 

Live Comment Preview: