I hope I am posting this in the right place... it involves some questions on the "best practices" way of architecting a Business/Data layer, so it sounds like architecture. However if this isn't the right place then accept my apologies.

I'm currently an intermediate .NET developer with C# and primarily ASP.NET. I'm trying to study advanced materials to become an "expert", and one of the main issues I run into is the best way to design a software solution. Nearly all of the teams I've worked on have snubbed the use of things such as Typed Datasets, instead preferring to write their own equivalent - this seems like reinventing the wheel to me, but when I asked the answer I got was basically "Typed Datasets are for the Morts".

I'm working on a small sample application to experiment with different patterns - nothing major, just playing around grabbing data from the Northwind database. In my Data layer I've used a Typed Dataset and then wrote a Mapper class with static methods as a wrapper around it, to encapsulate the actual calls to the dataset's classes (so the UI never knows it's dealing with typed datasets). So for example, the typed dataset is for the Products table in the NW database. I specified two methods in the dataset: GetProducts() which returns all products, and GetProductByID(@ID) which returns a specified product. Simple stuff. My mapper (ProductMapper.cs) has two static methods: GetProducts() that returns a ReadOnlyCollection or type Product, and Get(int ID) which returns a single product. Again, simple. The business layer is basically a DTO, only containing property definitions for the table.

My UI (I have both a Winforms GUI and an ASP.NET web page for the demo) calls the code like so:

Code Block

// Get all products
ReadOnlyCollection<Product> products = ProductMapper.GetProducts();
// Do something here, such as bind to a grid

// Get a single product
Product p = ProductMapper.Get(1); // sample hardcoded value
// Do something with the product.

Now, the code works. But let me get to the real meat of this post (sorry for it being so long-winded before I actually ask the question): Is what I'm doing "wrong" or "bad" As I've said, I'm an intermediate level developer but I'm used to working for small companies where I'm really the only developer - so it never mattered how I did things, and I admit I've done my share of quick-and-dirty hacks (i.e. data access logic in a button's click event). So now I'm trying to learn better methods so I can improve my skillset. I've worked with a few small teams in the past, and they would turn their nose at this approach and insist that it should be written by hand - writing by hand what already exists in the IDE seems like over-architecting a solution to me, although they were disciples of Agile Design so that might have been why, as well. Now, I don't come from a programming background; I got started by teaching myself VB.NET a few years ago for a project, so maybe that's why I'm more inclined to use "free" functionality from the IDE instead of shunning it and rolling my own.

Given that I am trying to learn the best way, am I going about it in the wrong way Or does it not matter for the most part, as long as I understand what it's doing behind the scenes

Thanks for the help, and for reading the entire post Smile

Re: Architecture General A few general architecture questions


I don't see any problems with typed datasets. As long as you understand that all it really is, is a dataset that the IDE auto-generated typed properties to access the data in the dataset, then I see no problem with it. They just make the programmer more efficient, but can also make them more naive if you don't know what is really going on.
As far as a general pointer for architecture, I have no specific answer to that either. Some people will over-engineer some projects, and other people will do the opposite. I say that it usually should involve the lifetime of the software and the size and complexity of the software that should determine the architecture. I say this because all the added architecture has a cost of time to the developer and possibly even readability if it is a real small project, and the developer uses every known design pattern known to man in the project. As a comment on your small example that you gave, I think that that is fine architecture that would probably meet the needs of many projects. However, architecture is a very expansive topic that like I said depends on the project which makes it harder for me to comment in a more specific way (and also the fact that I haven't been in the professional software development world for very long either (< a year)).

Re: Architecture General A few general architecture questions


If I were you I would definitley look at codegenration options for the dataccess layer.

A great generation option which I have personally tried is Nettiers, it will save ypu a lot of time and resources, as it will generate the dataaccess objects for you.

Take a look and tell me if it was helpful for you.

Re: Architecture General A few general architecture questions

Ed Hill

If it were not free I'd say you had shares in Nettiers LCCL; the way you spam the Arch forum with posts about it

It is a little elitist (and by that I mean arrogant) of the original posters collegues to deride him for a choice of architecture. If there was one correct architecture for all software developments we'd all be using it and much of the skill involved in assessing architectural trade-offs: development time, cost, reliability, scalability, security, maintainability etc, would make the job pretty boring (and this forum obsolete).

The original posters colleagues are probably of the opinion that typed datasets are going to be directly mapped to tables in the database (See Table Module pattern in Martin Fowler's website [better yet buy his P of EAA book and read it]). This is generally very quick to get up and running but you lack the ability to provide an expressive domain model (website and book again) which allows you to better represent domain concepts and use the full feature set of OO development without worrying how it's stored in tables (contentious point: normalised relational tables are for efficient storage, not for efficient domain modelling or providing protected variance by using polymorphism).

For example: If you were tasked with showing a large delegation of developers a new development technology and you only had an hour to showcase it and then delete the code you wrote, would you : a) fire up visual studio, drag and drop a few connections; controls. Double click on some UI widget, type some code and boom [winform|asp.net|web service|ajax|wpf|silverlight|next-tech] northwind, take your bow and a couple of idiot questions and leave, or b) spend time building a maintainable object model that is more easily maintained by the stream of developers that will come after you and is easily extended to incorporate most requirements changes over the lifetime of the application; get half-way and run out of time.

I value developers who write maintainable code over anything else and production code with any reasonable life span has to be maintainable (hardware is cheap compared to developer time). The architectural trade-offs always have to be considered in any development.

Hope that helps

Ed Hill

Re: Architecture General A few general architecture questions


First of all, I really hope you are kidding about me spamming the forum with posts on NETTiers. The reason you find som many posts on this template is that I get a lot of questions where I know the person asking them will be pleased with NETTiers, since I have been working on data access frameworks for over 5 years now. We have just finished a comparitive study on the different code generators out in the market, and this was definitly one of the top in our list (and free too!).

Second of all, I am not knocking typed datasets or other technologies, but I have found a lot of benefit from codegeneration over the years for countless production projects, We have saved hours and hours of development time as a result. I used to use typed datasets, but after I tried generating the data access layer for the first time I have never looked back.

Third of all, I am advocating codegeneration in general, and NETTiers just happens to be the framework I have found most beneficial over the years in terms of having a small learning curve and giving the greatest productivity boost at the same time.

Anything I post comes from either personal experience or extensive reading, so I don't see what is wrong with sharing personal experience with people, specially when it was something that you have used time and time again and shown to be useful.

Re: Architecture General A few general architecture questions

Ed Hill

It was meant to be tongue-in-cheek rather than abusive, I hoped that by reading the whole of my post you'd see my point regarding the multitude of factors that need to be considered and what would make something a good solution for one type of development a bad choice for another.

Perhaps if you extended your template to include a little bit of the architectural considerations weighed up in your 5 year study, showing how you came to chose the TableModule pattern (which I believe NetTiers uses) over other styles of architecture.

Saying use NetTiers to me says: your chosing the TableModule pattern so your sacrificing flexibility in being able to provide a business logic model based on either a low represeantional gap to aid understanding with a domain model or losing the ability to use OO concepts like encapsulation, cohesion and coupling in order to design a class structure that will be easier to maintain over time. It says that you have weighed up the maintainability aspects of an anaemic domain model against the immediate productivity of going directly from tables to entities, your essentially coding create, read, update, & delete statements and do not expect the business logic in the system to be too complex and it doesn't warrent the longer inital start up time a Martin Fowler, Eric Evans, Jimmy Nilsson DDD style domain model would require.

To someone who hasn't used these different styles on different sized projects, it's just going to sound like your telling someone to use a particular make of hammer when they are asking when they should use a hammer or a drill.

Actually code generation isn't really an architectural style it's an implementation detail, you can do TableModule, TransactionScript by writing the code yourself, it's still the same architectural style. You can acheive a TableModule solution by using configuration, no code is generated and you still have the same architectural style.

I personally think generated code is nasty looking, look at the code of the typed dataset the original poster was using or look at the code emitted by the XmlSerializer to serialise/deserialise objects, if a developer wrote code like that you'd buy them a copy of Code Complete and sit them at a desk without a computer until they have finished reading it. Code generation has its place but I've seen people resort to it instead of thinking about reusable code which as far as I'm concerned is only one step up from cutting and pasting code.

To further illustrate my point here's an example:

I have a high transaction system dealing with large amounts of data, millions of rows, not thousands. The database tables are split based on a combination of normalization (reducing duplication thus being cheaper to store on the expensive SAN, redundant, backed up disk) and also aligning to page size boundaries as getting close to the page size will result in an I/O bottleneck. This means that the database table structure may need to change independantly of the busines logic as you perform load testing (and you still get some surprises in live).If your using the TableModule pattern and a DBA wants to split a table based on it's size on disk or denomalise for performance and you have a million lines of code in a development, regenning the DAL isn't going to help if your entities are table aligned.

Re: Architecture General A few general architecture questions


The only thing I don't consider good about the design is making the methods ProductMapper.GetProducts() and ProductMapper.Get(1) static.