I've created a simple desktop application in C# 3.0 to learn some C#, wpf and .Net 3.5.
My application essentially reads data from a csv file and stores it in a SQL server CE database. I use sqlmetal to generate the ORM code for the database.
My first iteration of this app is ugly as hell and I'm in the process of refactoring it.
Which brings me to my question. How would you architect a desktop database app in C#?
What are the best practices?
Do you create a Database Abstraction Layer (DAL) which uses the sqlmetal generated code? Or is the generated code enough of an abstraction?
If you use DAL pattern, do you make it a singleton or a static member?
Do you use the View-Model-ModelView pattern with the DAL pattern?
Apologies if this seems like a long open ended question, but I have been giving this a lot of thought recently.
I see a lot of examples on how to architect an enterprise n-tier app in C# but not that many on architecting standalone desktop apps.
I would start with the Composite Application Guidance for WPF (cough PRISM cough) from Microsoft's P&P team. With the download comes a great reference application that is the starting point for most of my WPF development today.
The DotNetRocks crew just interviewed Glenn Block and Brian Noyes about this if you're interested in hearing more from them.
Even better, Prism is not nearly as heavy as the CAB was, if you're familiar at all with that from the WinForms days.
The answer is "it depends" as always.
A few things to think about:
You may want to make this fat client app a web app (for example) at some point. If so, you should be sure to keep separation between the business layer (and below) and the presentation. The simplest way to do this is to be sure all calls to the business logic go through an interface of some kind. A more complex way is to implement a full MVC setup.
Another thing you may consider is making the data access layer independent of the business logic and user interface. By this I mean that all calls from business logic into the DAL should be generic "get me this data" rather than "get me this data from SQL" or even worse "run this SQL statement". In this way, you can replace your DAL with one that accesses a different database, XML files, or even something icky like flat files.
In short, separation of concerns. This allows you to grow in the future by adding a different UI, segmenting all three areas into their own tier, or changing the relevant technology.
Before architecting anything you should define requirements for your app.
It's a common error of beginner developers - starting writing code ahead of thinking about how it would perform. My advice will be to try to describe some feature of you application. It will help you to feel how it should be implemented.
As for useful learning resources I would highly recommend you to take a look at CompositeWPF it's a project designed specifically to teach developers best practices of desktop app development.
I'd start with Jeremy Miller's Build Your Own Cab series.
I was an early CAB adopter. I learned a lot from digging into that technology and reading all the .NET blogs about application architecture.
But recently I had a chance to start a new project, and instead of using CAB I went with StructureMap & NHibernate and borrowed some of the patterns that Jeremy uses (in particular, his way of handling event aggregation). The result was a really simplified, hand-tooled framework that does everything I need and I love working with it.
As to the specifics of your question: I use a Repository for data access. I initially wrote some ADO.NET code and used data readers and mapped my objects. But that got old real fast, so I grabbed NHibernate and was really pleased. The repositories use NHibernate for data access, and my data access needs are pretty simple in this particular app.
I have a service layer (exposed via WCF, Duplex channels) that utilizes the repositories. My app is basically client-server with real time updating (and I know your question was just about clients, but I would use the same technologies and patterns). O
n the client side I utilize MVP with StructureMap for IoC and some very simple event aggregation strategies for cross-class communications. I code to interfaces for just about everything. The only other thing I did was borrow from the CAB the idea of a flexible "Workspace" for dynamically displaying views. I wrote my own Workspace interface though and implemented my own DeckWorkspace and TableWorkspace for use in my app (these were really simple things to write).
A lot of my decisions in this most recent application were the result of experience and pain I felt using other frameworks and tools. I made different decisions this time around. Maybe the only way to really understand how to architect an application is to feel the pain of doing it wrong beforehand.
I would say yes, it could easily be structured towards smaller applications. There is a learning curve towards getting started, but honestly, it helped me understand WPF better than attempting to start from scratch. After starting a project with CompositeWPF and then starting another project without it, I found myself attempting to duplicate features of CompositeWPF on my own because I missed those features! :)
Related
As a part of my master thesis I am going to develop a software for heat optimization in apartments. This software will we middle-sized and will have a web based interface towards customers and an interface towards sensors (which is placed in the apartment). I'm considering a multi-tier architecture. Many of the objects in the system will have its own database table. This means lots and lots of code and SQL statements (and time) for saving and retrieving the objects. Is this the standard way of developing software still?
I have considered to use NHibernate but I have som doubts, the primary reasons are:
I do not have much experience in software development.
The session handling seems quite complex, especially if one must have a businesslayer providing functionality to both a webinterface and to a sensor interface. Because of the lazy loading I need to have the session active at these interfaces but then the presentation layer is aware of the data acess layer which is not desireable.
So, is there any alternatives? I am using MySql 5.5 and C#.
The current orthodoxy in web development is MVC; in Microsoft land, that means ASP.Net MVC. The MS site has a great tutorial describing the way you integrate your "model" classes, representing your business domain, with a database.
ASP.Net MVC also provides a way of building a Web API - this should allow your sensors to communicate with the application using the same underlying model classes.
Seems to me you have an inherent logical partition that should lead to an abstraction of the sensor-database communication into one layer, and the customer-database communication into another layer. The sensor-side could provide a read-only set of interface(s) to provide information (as needed) to the customer side, while the core functionality for your heat optimization work can reside essentially in the middle.
If you spend some time thinking about how these pieces should be partitioned, allowing you to define clean interfaces between the two, the complexity of the overall project should diminish at least some.
I would carefully consider NHibernate if you "I do not have much experience in software development." While it is an amazing tool and extremely powerful - the learning curve can be steep and depends how much time you want to commit to learning it. Having said that however, I am really happy with it.
I am trying to develop a .NET 3.5 service application that uses:
WCF for the service layer
Business object layer to encapsulate our business logic (and isolate the service and data access layers)
Linq-to-SQL for the data access technology
Unity for dependency injection
Enterprise Library 5 with the following:
Validation Application Block
Exception Handling Application Block
Logging Application Block
We are also looking to follow TDD and want persistence ignorance (PI) as we may be changing data access technologies to either NHibernate or EF when we upgrade to .NET 4.0 later in the year and we want to minimize the impact such a change will have by isolating it to just the data access layer.
I have been working with the application for a little over a week now and have quite a bit of it working. I have yet to get the EHAB or LAB implemented successfully, validation is only partly implemented and PI is non-POCO based because we are required to support the designer (as opposed to using XML mapping). We are using the repository pattern with interfaces for PI.
Can anyone point me to some quality (real-world) example solutions using these technologies together? That's probably the best way to address my questions and concerns because the articles I've referenced thus far only touch on one or two aspects of my solution and things aren't working exactly the same as they describe when I wire all of this together.
Have you tried looking through p&p hands-on labs:
download sample solutions and instructions
These are pretty easy to work through, giving you guidance and usage patterns.
I have started a WinForms project a few weeks ago and as I did not really know what features I wanted, I just added them along the way. This now caused a horrible mess where my MainForm is a big ball of mud and where for example some important state changes are triggered by UI elements to the point I have to call the OnChange Event of a Control in order to change some state in the database.
In short: I've just started a new project where I want to take a better approach. I just don't know which would be the "good" one. In ASP.net MVC, I found the MVVM Pattern really useful, but on the Desktop, MVVM seems to be only intended for WPF, not for WinForms.
The other approach is a three-tier-architecture: I have my Database-Class which currently talks directly to the UI. I now create a new Static Class ("ApplicationState") that talks to the database and fires events to tell the UI "Hey, Something changed!". The UI would manipulate the State which will then handle the database persistence and again raise Events if the UI needs updating. The point here is that the ApplicationState class never modifies the UI directly, but that the UI subscribes to Events. That looks like a clean/"MVC-y" way of doing it, but maybe I am overlooking something here?
Basically my ultimate goal would be to have the UI completely independent from the database layer just to make sure I don't wire in business logic into the UI again.
Don't throw in the towel on MVVM - it's valid for WinForms as well. Basically, if you use data-binding, you have to make a decision about what your objects will bind to. Often, especially for more complex UI, you dont want to bind directly to your domain objects, you want to build specialized classes (sometimes wrappers) that your UI can bind to which provide everything the view needs (the essence of MVVM) and the technique works just as well with Winforms.
A good series on WinForms Model-View-Presenter approach can be found at
The Build Your Own CAB Series Table of Contents
What I would always go for (first) is to have a layered application
Presentation Layer (JUST UI and databinding logic)
Interface Layer to the Business Layer (defining the contracts for accessing the BL)
Business Layer implementation (the actual logic, data validation etc...)
Interface Layer to the Data Access Layer (defining the contracts for accessing the DAL)
Data Access Layer implementation
This organizes your application extremely well. Then I'd look for some MVC kind approach. I did not develop so much with WinForms, more with Asp.net and some Java Desktop clients (where I used MVC). WinForms works more with the .Net databinding approach (DataSource, DataMember,...). You should go for that approach instead of trying to force something other. I found that it doesn't match that well.
What's always useful is to lay out our UI logic into different controls (like UserControls in Asp.net). This facilitates reuse.
NDepend documentation comes with some pretty cool and advanced online blog posts, articles and white books concerning architecture of .NET code.
Advices on partitioning code through .NET assemblies
Control Components Dependencies to gain Clean Architecture
Re-factoring, Re-Structuring and the cost of Levelizing
Evolutionary Design and Acyclic componentization
Layering, the Level metric and the Discourse of Method
Fighting Fabricated Complexity
Also, if you want to continuously check that your UI code is independent from your database code, you can write easily some Code Query Language rules that will be checked live at development time in Visual Studio:
Keep your code structure clean
Just start writing unit-tests for everything you can think of. As some pieces will turnout difficult to unit-test because of tight coupling to the WinForms, separate them out. Clean. Wash. Repeat.
Nido framework is good. However it is just for your back-end architecture. It will give you a solid, flexible, and simpler back-end with t4template. It prove to be having a very good architectural pattern. Furthermore it can plug not just with WinForm but with any other (MVC ASP.NET etc) front-end too..
Then again RocketFramework is also good
Link1: http://rocketframework.codeplex.com
Link2: http://nidoframework.codeplex.com
Our rule of thumb is to lean towards MVC for most websites due to the stateless nature of the web. Unless you're trying to provide a very rich web experience and bring in silverlight, then you should go with MVVM. XAML goes hand to hand with MVVM and can be your smart client choice as well (or a nice MVCP pattern).
True MVC is almost impossible to uphold in any other circumstance due to the fact that controllers are suppose to handle all input. Most non web architecture has controls that will provide this for you. In fact, most say that ASP.NET MVC is a hybrid MVC anyways but it's very good in my experience.
Okay,
I found some nice answers above but as per my 4+ years of experience in winform, I can say that you can use dotnet remoting for this purpose. In simple words, you need to create one solution for your business logic and client side works and another solution for connection with the database which you can called as a server. Both solution should contain some common projects and then you can easily works on your application without worry about your database.
I would suggest you to read about dotnet remoting.
Hope, this answer is helpful.
I have to develop a basic "line of business" application with the usual functionality like orders, stock control, sales, reports, etc.
I will use WPF to develop this application to run on Windows but I want to develop it "open" so I can do a Windows Forms application using the same structure (maybe to run over Mono) or even a Silverlight module. Can someone that did something like that (and survived) give me a sugestion on a guideline or something like that where I can find good practices? I'm a Delphi developer with some intermediate knowledge on C# but there are so many "amazing" libraries, frameworks and patterns that I'm a little lost on what would be good for that project.
Something like: Use EF (maybe wait for ef4?) or nHibernate, or ADO.NET, and expose your data using WCF, or webservices, or forget Mono because of the flexibility loss, etc. Can someone give me a tip on how you would do it? If someone has a bad experience in this type of project, it would be nice to hear from you as well. There is a lot of learning in the wrong decisions too :)
Mono doesn't implement WPF, it's not even on the roadmap. I'm not sure about Entity Framework...
You could probably do it in Silverlight (which has an open source implementation), but it's not ideal for creating desktop (although it is possible since Silverlight 3)
Where do I start?
First, from your description, you're in over your head.
Second, you're trying to pick a technology stack when everything is new to you.
In the best situation, I'd recommend a good training class in a few of the technologies you mentioned so you get a better understanding of them. I'd also recommend a mentor, someone who's done this before.
Reality though, may not allow for training or a mentor. In that case I'd recommend writing several real-life throw away programs. Take one piece of business functionality and try to write it in a few of the technologies you mentioned. If one feels better, and gives you what you want DECISION MADE! Don't stop with the first one that seems to work, try some more.
You should also listen to some good podcasts. I recommend Dot Net Rocks for a good grasp of the technology. The earlier podcasts for this site were also a very good source for some design discussions StackOverflow podcast
Best of luck.
I had to do something very similar recently in WPF. I have an ASP.NET background, but I have never worked with WPF (or WinForms for that matter), and it had me stumped for a while, but the longer I have been working on it (about 3 weeks now), the easier it has gotten. I really just searched Stack Overflow and Google for code snippets similar to what I was doing, and worked through them and changed them as needed. My company bought a book that helped me out as well (It was WPF Unleashed published by Sams), and it was pretty good. I do wish you luck on your first WPF app.
If you separate the business model and business logic from the user interface,
using MVC (Model View Controller) or MVVM (Model View View-Model) or a simular design pattern,
then you can have multiple user interfaces connected to the same business model + business logic and even connect the same user interface to other business models + business logic.
Thank you all for your suport... Brad, I'm already following your advices, doing some test cases to see what looks good... my problem is that altough I can develop an application in WPF and have a intermediate understanding in using the wpf databindings, generics, linq, anonymous objects, all the cool stuff, I always hear about this and that as the solution for all the worlds problems (like mvvm, or parallel programming, or functional languages, etc) and makes me feel "wrong" in my decisions and a bad developer if I do not use any of this nice technologies. I know the concepts but do not dominate it, and seems a lot of things to learn, sadly I do not have that much time.
Thomas, exactly because mono do not support WPF i want to make the application as isolated as i can, so I can do a simple winform layer to manipulate the data.
darthnosaj, thank you, I'm doing that too, searching internet and found much information (and this nice site full of hellpful people :) )
And Danny, thats what i think i need... will take a look on some sample applications using mvvm and see if that works for me. For what i heard is almost a crime not to use in that case in wich I want that kind of isolation.
Again, thanks all :)
I would suggest you keep your application N-Tier. Make all the entities, data adapter, and business logic separated from the actual desktop application. This way you can use WPF on the Windows platform and use Mono/GTK# on the Linux/Mac platforms.
You will only need to write duplicate code to support the actual GUI application functionality, while your code from the separate entity/data access/business logic library (e.g. DLL/class library) can be used in both your WPF and Mono/GTK# projects. Just add the DLL as a reference to the WPF and Mono/GTK# projects.
There is a good video from Channel 9 on building N-Tier applications
There is also MSDN documentation and guidelines on building N-Tier applications
I'm trying to move toward TDD, ORM, Mocking, ect. I need a good example of a line of business app that uses an ORM preferably NHibernate.
It has to be open source and use the repository pattern.
I learn best by example, I have played around with the repository pattern and unit of work pattern but not in any meaningful applications.
I'm familiar with IoC (I use unity), WCF, Workflow Foundation, WPF, Smart Client Software Factory, Webclient Software Factory, ect.
I've learned all the "basics" (they are pretty advanced principals to be called basics, IMO) I just can't seem to put it all together.
The applications we write follow all "best practices" as far as architecture, we have a business logic layer, data access layer, MVP, MVVP, MVC, ect. but there is never any code in our BLL's besides
return dal.GetBlahBlahBlah();
I have to ask myself where is all my business logic???
Probably 95% of our data access is through stored procedures and I have to assume that its all if the database. Some of these SP's are huge and have lots and lots of if statements, case statement, and the occasional cursor.
As mentioned above I know how to use all of these cool technologies but it seems like the only thing I'm using them for is to make a really, really overcomplicated, overly architecture'd reporting tool for sql server.
If ALT.NET is the better way, if having all of your business logic in the code is the better way, there has to be an open source application out there that puts it all together in all the right ways
I haven't come across any LOB applications but I have heard that Cuyahoa is an excellent example of how to use NHibernate.
I am familiar with the code in Suteki Shop, an e-commerce platform using ASP.Net MVC and Linq-To-Sql which is active at the moment and being re-factored very well and should provide you with some insight in to what you're attempting.
Penultimately, there is Rob Conery's MVC StoreFront. Rob is the master of screencasts and presents a great insight in to learning TDD.
My final link is summer of nhibernate another series of screencasts this time specifically on using NHibernate