Article browser
Table of contents
- Introduction
- Generic functionality
- Target framework specific subjects
- Writing n-tier applications using MVVM
1. Introduction
Welcome to part 0 of the article series about Catel. Quite a strange part, don’t you think? Well, we hear from a lot of people that the real power of Catel cannot be seen at first sight. When people start using Catel, they become very happy, but why should they choose Catel?
This article tries to explain why you should use Catel as the (or one of the) frameworks when developing WPF, Silverlight, and Windows Phone 7 applications.
This article is separated into several sections, one general one, and the rest is specific for the different frameworks that are targeted by Catel. It’s recommended to read the general part first, and then you can skip to the target framework you are interested in.
This article is not about in-depth explanations of all the functionality. If you are looking for a deep-dive into Catel, it’s recommended to read all the other articles which all focus on a specific part of the framework. This article is more of a summary of what Catel has to offer.
2. Generic functionality
2.1. It’s your choice
We care a lot about the freedom you need as a software developer. Most frameworks require a developer to learn its conventions, or use the whole framework or nothing at all. When we, the developers of Catel, use an external framework, we choose that framework for a specific reason, and don’t want to be bothered by all the other superb stuff it has to offer (maybe later, but not now).
During the development of Catel, we tried to maintain this freedom aspect which is very important to us. Therefore, all functionality is loosely coupled. Sounds great, but everything is called loosely coupled nowadays. Catel contains a lot of different aspects, such as logging, diagnostics, Reflection, MVVM, user controls, windows, etc. All these aspects are complementary to each other, but the great thing about Catel is that you decide whether to use just one, some, or maybe all aspects.
As an example: you have a legacy application and want to use the DataWindow to write simple entry windows, but you are not ready for MVVM yet. No problem, the DataWindow is complementary to MVVM, but does not require it. Therefore, you have all the freedom to use just what you need, whenever you need it.
Most frameworks require a bootstrapper that completely decides how your application structure should look like. For example, your Views must have this name, your controls must have that name. Again, in Catel, we wanted to give you the freedom you would expect from a framework.
The great thing about this freedom is that the different aspects of Catel can be used side-by-side with other frameworks, so you as a developer can use the best framework for every aspect in your application.
2.2. Data handling
The first thing that is important is that lots of developers lose way too much time writing custom serializable objects. Serialization is a field of expertise, and only a handful of developers I know really master the serialization of objects (think of version changes of the assembly, class changes (new or removed properties), etc.). Most developers think they master serialization by creating a BinaryFormatter
object like the code belows show:
BinaryFormatter serializer = new BinaryFormatter();
var myObject = (MyObject)serializer.Deserialize(stream);
Most developers don’t know that Binary Serialization breaks when:
- You change the version number of your assembly;
- You add or remove a property or field;
- You add or remove an event.
And even if you know, it takes a lot of knowledge and courage to start beating the beast of burden. Like every developer, I also encountered this and was writing backwards compatibility code until I had enough of it and decided to master the field of serialization. The result is the DataObjectBase
class, which can be used as a base class for all data objects that need to be held in memory and maybe serialized to disk (or a stream, or XML, or ...).
2.2.1. DataObjectBase class
Using the class is extremely simple. Just declare a new class that derives from DataObjectBase
and you are ready to go:
#if !SILVERLIGHT
[Serializable]
#endif
public class MyObject : DataObjectBase<MyObject>
{
public MyObject() { }
#if !SILVERLIGHT
protected MyObject(SerializationInfo info, StreamingContext context)
: base(info, context) { }
#endif
}
As you can see in the code above, the MyObject
class derives from DataObjectBase
and provides an empty constructor, but also a constructor that is used for binary deserialization. The code above might look complex, but it is created using the dataobject code snippet, and you only have to type the name of the class.
2.2.2. Defining properties
Defining properties for the class is very easy, and works the same like dependency properties. The advantages of this way of defining properties are:
- Properties defined like this are automatically included during serialization; no need to specify complex data contracts;
- You can specify a default value for a property which will be used when the class is constructed or the property is not found during deserialization (in case this property is added to an existing class);
- The
PropertyData
object can be used to retrieve property values so the compiler checks for errors;
- You can directly subscribe to change notifications, and all properties automatically support
INotifyPropertyChanged
out of the box.
Below is the code that defines a new property Name
of type string
:
public string Name
{
get { return GetValue<string>(NameProperty); }
set { SetValue(NameProperty, value); }
}
public static readonly PropertyData NameProperty =
RegisterProperty("Name", typeof(string), string.Empty);
A registered property can be excluded from serialization if wanted. When the object is deserialized, the default value will be used for the property in that case.
2.2.3. Serialization
I have mentioned serialization a few times already. Let’s take a look at how easy it is to (de)serialize your objects no matter what assembly version you use. First of all, instead of deriving from DataObjectBase
, it is very important to derive from SavableDataObjectBase
.
Depending on the target framework, several options are available as serialization modes:
- Binary;
- XML;
- DataContract;
- JSON.
The code below shows how to save an object (which can, of course, be a complex graph of nested objects):
var myObject = new MyObject();
myObject.Save(@"C:\myobject.dob");
Looks too easy, but this really is the only thing you need to do. You can specify the serialization mode in the several available overloads of the Save
method.
Loading is as easy as saving, as you can see in the following code:
var myObject = MyObject.Load(@"C:\myobject.dob");
2.2.4. Functionality provided out of the box
The DataObjectBase
provides a lot of functionality out of the box. A few points I want to mention are:
All properties registered using the RegisterProperty
method automatically take care of change notifications.
It is very easy to set field and business errors using the SetFieldError
and SetBusinessError
methods that can be used in the overridable ValidateFields
and ValidateBusinessRules
methods.
The data object can automatically create an internal backup and restore it, if required, using the IEditableObject
interface.
As told many times before, using the SavableDataObjectBase
, you can simply save your file to a stream (file on disk, stream in memory, etc.).
- INotifyPropertyChanged
- IDataErrorInfo
- IEditableObject
- Serialization
Keep in mind that this class is not suitable for database communication, there are much better ways to handle this (ORM mappers such as Entity Framework, NHibernate, LLBLGen Pro, etc.).
This API is located in the Catel.Core assembly which can be used without WPF (thus in ASP.NET, Windows Forms, etc.).
2.3. MVVM basics
The last few years, MVVM has become the number one pattern to write applications using WPF, Silverlight, and Windows Phone 7. The actual pattern is very simple, but there are some flaws and questions lots of MVVM users have, such as:
- How to show modal dialogs or message boxes inside a View-Model?
- How to run processes inside a View-Model?
- How to let the user select a file inside a View-Model?
In my opinion, this is where the good frameworks separate themselves from the bad ones. For example, people actually calling MessageBox.Show
inside a View-Model are using the pattern wrong. If you are one of the developers that directly call a MessageBox
inside a View-Model, ask yourself this: who is going to click the button during a unit test?
Before we actually started developing Catel, we did lots of investigations to make sure that the MVVM pattern was really useful in Line of Business (LoB) applications and does not miss the finishing touch. Thanks to this investigation and research, we created a solid MVVM framework which solves all the known problems of the MVVM pattern.
2.3.1. ViewModelBase
Like almost every other MVVM framework, the base class for all View-Models is ViewModelBase
. This base class is derived from the DataObjectBase
class explained earlier in this article, which gives the following advantages:
- Dependency property a-like property registration;
- Automatic change notification;
- Support for field and business errors.
Because the class derives from DataObjectBase
, you can simply add field and business errors that are automatically being reflected to the UI. Writing View-Models has never been so easy!
2.3.2. Model to View-Model mappings
During of the use of the MVVM pattern, we noticed that lots and lots of developers have a Model, and map the values of the Model to all properties of the View-Model. When the UI closes, the developers map all the properties back to the Model. All this redundant code is not necessary when using the View-Models of Catel.
In Catel, we have created attributes that allow you to define a property as a Model. A Model is a property that a part of the View-Model represents to the user. A View-Model might have multiple Models if it is a combination of several Models.
Defining a Model is very simple, you only have to decorate your property with the Model
attribute:
[Model]
public IShop Shop
{
get { return GetValue<IShop>(ShopProperty); }
private set { SetValue(ShopProperty, value); }
}
public static readonly PropertyData ShopProperty =
RegisterProperty("Shop", typeof(IShop));
Using the Model
attribute is very powerful. Basically, this is the extended functionality in the View-Model. If the model supports IEditableObject
, BeginEdit
is automatically called in the Initialize
of the View-Model. When the View-Model is canceled, the CancelEdit
is called so the changes are undone.
When a Model is defined, it is possible to use the ModelToViewModel
attribute, as you can see in the code below:
[ViewModelToModel("Shop")]
public string Name
{
get { return GetValue<string>(NameProperty); }
set { SetValue(NameProperty, value); }
}
public static readonly PropertyData NameProperty = RegisterProperty("Name", typeof(string));
The ViewModelToModel
attribute in the code example above automatically maps the View-Model Name
property to the Shop.Name
property. This way, you don’t have to manually map the values from and to the Model. Another nice effect is that the View-Model automatically validates all objects defined using the Model
attribute, and all field and business errors mapped are automatically mapped to the View-Model.
Summarized, the Model
and ViewModelToModel
attributes make sure no duplicate validation and no manual mappings are required.
2.3.3. Commands
Commanding is perfectly supported by Catel. Catel supports Command classes, which is also known as RelayCommand
or DelegateCommand
in other frameworks. Defining a command on a View-Model is very easy, as you can see in the code below:
Edit = new Command<object, object>(OnEditExecute, OnEditCanExecute);
public Command<object, object> Edit { get; private set; }
private bool OnEditCanExecute(object parameter)
{
return true;
}
private void OnEditExecute(object parameter)
{
}
There are some people who don’t like the ICommand
implementations. For example, Caliburn (Micro) uses convention and does not require the creation of a command. There are a few downsides for that:
- It requires you to make sure the name of the control is the same as the method;
- It is not clear that it is actually a command if you are not fully familiar with the conventions;
- The methods need to be public (otherwise, how are you going to invoke the commands during unit tests?), which make them freely available (and that’s not something we like);
- You will always have to invoke
CanExecute
yourself again in Execute
, because you have no guarantee that the source of Execute
is actually the convention mapping;
- There is no way to manually refresh the
CanExecute
state on the bound controls.
2.3.4. Services
Services are the way Catel solves the issue where you need to show messages to the user, let the user run processes, etc. The ViewModelBase
has a GetService
method to retrieve the actual implementation of an interface via an Inversion of Control (IoC) container. For WPF and Silverlight, Catel uses Unity. For Windows Phone 7, a custom implementation of IoC is used.
The great thing about services in Catel is that, by default, the real implementations are registered with the Unity container. Via the IoC container, you can register test implementations (which, of course, also ship with Catel) so you can decide the result of, for example, a message box click. This way, you can simulate a user clicking OK, or if you want, you can also simulate Cancel. This way, you can unit test all the available possibilities a user can execute on the View-Model.
Using the services is very easy. As told earlier, the GetService
method retrieves the actual implementation of the service. For example, to show a message to the user, you can use the following code:
var messageService = GetService<IMessageService>();
messageService.ShowError("An error occurred");
All the services can be used this easily. Catel supports several services. Below is a table with all the services available per target framework.
Service name and description |
WPF |
Silverlight |
WP7 |
ILogger - makes it possible to write messages to the log
|
|
|
|
ILocationService - retrieve geographical locations
|
|
|
|
IMessageService - show message boxes
|
|
|
|
INavigationService - navigation service
|
|
|
|
IOpenFileService - lets the user select a file to open
|
|
|
|
IPleaseWaitService - runs a delegate on the UI thread and shows a busy indicator
|
|
|
|
IProcessService - run processes
|
|
|
|
ISaveFileService - lets the user select a file to save
|
|
|
|
IUIVisualizerService - show (model) windows
|
|
|
|
Of course, you can also write and register your own services.
2.3.5. Communication with other View-Models
Most frameworks require you to set up complex message systems (messengers) or other techniques to communicate with other View-Models. The downside of this approach is that once a View-Model is written in module X, and you are interested in the View-Model, the developer of module X must take care of notifying other View-Models. We think this is not the responsibility of the originating View-Model.
If a View-Model is interested in the changes of another View-Model, it’s the responsibility of the View-Model that is interested to watch the View-Model, not the other way around. To be notified of changes on other View-Models, the only thing you have to do is to decorate a View-Model with the InterestedIn
attribute, like shown in the code below:
[InterestedIn(typeof(FamilyViewModel))]
public class PersonViewModel : ViewModelBase
Then, inside the PersonViewModel
(which is interested in the changes of FamilyViewModel
), you only have to override the OnViewModelPropertyChanged
method:
protected override void OnViewModelPropertyChanged(IViewModel viewModel, string propertyName)
{
}
It is possible to be interested in multiple View-Models. Since the View-Model is passed to the OnViewModelPropertyChanged
method, it is very easy to check the type of the View-Model.
2.3.6. Nested user controls problem
In MVVM, there is a complex architectural problem that we call the “nested user controls problem”. Until now, we have not found any other framework that is capable of solving this issue in a clean manner. The problem is that nested user controls should normally get their own View-Model, but how do you manage such a thing? We see several (bad) solutions, like:
- Defining nested View-Models on another View-Model;
- Defining the properties of nested user controls on the top View-Model and assume properties inside the nested user control.
Below is a graphical representation of the problem:
Regular MVVM Frameworks
Catel MVVM Framework
As the images above show, the method that Catel uses to solve the problem is much more professional. Below are a few reasons:
- Separation of concerns (each control has a View-Model only containing the information for itself, not for children);
- User controls are built so they can be re-used. Without the user controls to be able to have their own View-Model, how should one actually use user controls with MVVM?
UserControl<TViewModel>
is able to construct a View-Model based on the actual datacontext of the user control. For example, when you define a nested user control, the only thing you’ll have to do is to make sure that the datacontext of the user control has an object that can be injected in the View-Model that belongs to the user control.
As an example, say we have a Person
control. This Person control can only be constructed with a valid IPerson
instance (the only constructor of the View-Model available). Then this is the way to define it in XAML:
<Controls:PersonControl DataContext=”{Binding Person}” />
The user control notices that the datacontext has changed, and tries to construct the PersonViewModel
with the real datacontext, in our case, an instance of the IPerson
interface. Then, it auto magically transforms the IPerson
object into a PersonViewModel
and the control has its own View-Model.
2.4. User Interface
As we have probably told you many times before, Catel is more than just another MVVM framework. It also provides lots of UI elements out of the box. The controls below are the most popular ones.
2.4.1. InfoBarMessageControl
InfoBarMessageControl
is able to show warnings and errors to the user using the IDataWarningInfo
and IDataErrorInfo
interfaces. The control is very useful to show the current state of a window or control to the user in a consistent way.
2.4.2. DataWindow
When developing software in WPF, I always need the following three types of windows:
- OK / Cancel buttons for data windows;
- OK / Cancel / Apply buttons for application settings / options;
- Close button on windows for action windows.
Creating these windows is just boring and the steps are always the same:
- Create a
WrapPanel
at the bottom of the window
- Add the buttons with the same
RoutedUICommand
objects over and over again
The DataWindow
class makes it much easier to create these basic windows, simply by specifying the mode of the window. By using this window, you can concentrate on the actual implementation, and you don’t have to worry about the implementation of the buttons itself, which saves you time! In the example below, the only thing that is coded manually in XAML are the actual input controls (textboxes).
2.4.3. PleaseWaitWindow
PleaseWaitWindow
is a great window to show during long operations. There is also a PleaseWaitHelper
class to make it even easier to use the PleaseWaitWindow
.
2.5. IO
What a lot of people don’t know is that Catel offers an extended API for IO handling. Now you probably ask yourself why. The following additions are made with the IO framework:
- Support for files and directories longer than 255 characters;
- Combine multiple paths or URLs together, like
Path.Combine(“C:”, “Windows”, “Temp”);
.
The API is designed to match the System.IO
style, so the usage is very intuitive.
This API is located in the Catel.Core assembly which can be used without WPF (thus in ASP.NET, Windows Forms, etc.).
2.6. Reflection
Internally, Catel uses lots of Reflection to make sure all of the functionality promised actually gets done. This chapter explains a few advantages of these Reflection implementations, which are not meant to fully replace the .NET Reflection classes. The Reflection classes of Catel are more an addition to the default classes.
The assembly extensions are mostly created to create an equal behavior for all the different target frameworks of Catel. For example, in WPF, we can simply get the loaded assemblies by using the current AppDomain
. However, Silverlight requires us to query the current Deployment
object. For Windows Phone 7, it’s even harder to get the loaded assemblies. By implementing the differences inside a separate class, all the shared classes between the target frameworks can be shared.
This API is located in the Catel.Core assembly which can be used without WPF (thus in ASP.NET, Windows Forms, etc.).
2.7. Diagnostics & logging
Catel uses log4net as the base for all the logging activities. It does provide additional functionality and extension methods to make it even easier to log exceptions and custom messages. Because Silverlight and Windows Phone 7 don’t have logging capabilities (client side), the ILog
implementation is just a dummy one.
This API is located in the Catel.Core assembly which can be used without WPF (thus in ASP.NET, Windows Forms, etc.).
2.8. Quality
Every framework claims to provide perfect quality. We wanted to go further than that. Therefore, more than 450 unit tests are written to prove that Catel provides quality and consistency. The unit tests are shared between WPF and Silverlight to make sure that the expected behavior is the same for both frameworks. This way, we tried to make sure that there is no loss in functionality for Silverlight, where we succeeded on most points (some things are just not possible in Silverlight).
2.9. Examples & documentations
Examples and documentation are very important to us. Therefore, each framework implementation has one or more example applications to show how to use the several aspects per target framework.
Catel is also very well documented. Besides lots of articles and blog posts, it also includes reference documentation with all the class definitions and their meanings.
Besides examples and documentation, Catel also offers project and item templates per target framework. This way, you don’t have to do a lot of the plumbing and let the tools (Visual Studio) do it for you. Besides the templates, Catel also ships code snippets which are very important if you want to be able to rapidly write software using Catel.
Last but not least, it is very important to us that you like Catel. Therefore we provide very good support on the discussion boards on the CodePlex project site. You can also e-mail one of the project members personally if you have a question with sensitive information.
3. Target framework specific subjects
As you probably know by now, Catel supports Silverlight implementations. Silverlight is a very popular platform for software development, but it lacks a lot of features that are already available in WPF. Therefore, with the development of Catel, we tried to even the functionality of all available classes and controls available in Catel.
We tried to implement the Windows Phone 7 implementation the same way, but there are a lot more things to keep in mind when developing a framework for Windows Phone 7, such as performance and a totally different approach of UI and state management.
3.1. Automatic refresh of commands in Silverlight
In Silverlight, commands are not re-evaluated automatically because there is no CommandManager
that calls the CanExecute
on every routed event. If the user solves an error in the window by, for example, adding a value in an empty field, the CanExecute
state of the OK or Save command is not updated (and still is disabled). Other frameworks require the developer to manually refresh the commands.
Catel offers a clean way of providing the same behavior of WPF. Thanks to the ViewModelBase
property InvalidateCommandsOnPropertyChanged
(which is enabled by default for Silverlight and Windows Phone 7), all the ICommand
implementations on the View-Model are automatically re-evaluated for you. This way, the user will immediately see the OK or Save button become enabled after setting the value.
3.2. Serialize data to isolated storage in Silverlight and Windows Phone 7
When developing software for Silverlight or Windows Phone 7, you have access to isolated storage. SavableDataObjectBase
supports saving and loading of complex graph objects to isolated storage out of the box. To save an object (including all the child objects), you can use the code below:
using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var isolatedStorageFileStream =
isolatedStorageFile.OpenFile("UserData.dob",
FileMode.Create, FileAccess.ReadWrite))
{
myObject.Save(isolatedStorageFileStream);
}
}
To load the data again, you can use the following code:
using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isolatedStorageFile.FileExists("UserData.dob"))
{
using (var isolatedStorageFileStream =
isolatedStorageFile.OpenFile("UserData.dob",
FileMode.Open, FileAccess.Read))
{
return MyObject.Load(isolatedStorageFileStream);
}
}
}
3.3. Navigation on Windows Phone 7
Navigation on Windows Phone 7 is very important. The navigation works the same like the web, thus with request variables. In Catel, it is very easy to navigate to another View (Model) using INavigationService
.
To navigate to another View directly, simply use this code inside your View-Model:
var navigationService = GetService<INavigationService>();
navigationService.Navigate("/UI/Pages/MyPage.xaml");
Of course, you can also pass parameters without a hassle:
var parameters = new Dictionary<string, object>();
parameters.Add("MyObjectID", 1);
var navigationService = GetService<INavigationService>();
navigationService.Navigate("/UI/Pages/MyPage.xaml", parameters);
The navigation service automatically converts this into the following URL:
/UI/Pages/MyPage.xaml?MyObjectID=1
3.4. Retrieving and simulating geographical locations on Windows Phone 7
The Windows Phone 7 device has a great feature: it can retrieve the current geographical location via GPS. However, how can we implement this correctly in MVVM? In Catel, a separate service is available to get the geographical location. The usage is very simple:
var locationService = GetService<ILocationService>();
locationService.LocationChanged += OnCurrentLocationChanged;
locationService.Start();
It is very important to stop the service when you no longer need it (think about the battery of the user):
var locationService = GetService<ILocationService>();
locationService.LocationChanged -= OnCurrentLocationChanged;
locationService.Stop();
In the OnCurrentLocationChanged
event, you can simply query the location from the EventArgs
:
private void OnCurrentLocationChanged(object sender, LocationChangedEventArgs e)
{
if (e.Location != null)
{
MapCenter = new GeoCoordinate(e.Location.Latitude,
e.Location.Longitude, e.Location.Altitude);
}
}
4. Writing n-tier applications using MVVM
We get a lot of questions from users about how to implement an n-tier application using MVVM. Most people think that MVVM replaces the business layer, but that is not the case. This chapter explains a few possibilities of how to write line of business (LoB) applications using MVVM, which you can make as complex or as easy as you want to.
Depending on the complexity and the requirements of the end-user, you might decide to use a multi-tier architecture for your software. We don’t believe in a single standard, but in a pragmatic approach where the number of tiers is decided again for every project to make sure no overhead is created, but no layers are forgotten as well.
Each n-tier description in this chapter shows, in a graphical way, how MVVM should be used inside the architecture. A long time ago, the n-tier model was developed to create a separation of concerns. In these days, a data access layer (DAL) was a complex thing on its own. Nowadays, there are tons of ORM mappers which generate the DAL for you. A few of these ORM mappers, such as LLBLGen Pro, allow you to add custom validation on entities and combine the DAL with some (or in simple applications, all) business functionality.
4.1. 2-tier applications
Writing a 2-tier application should only be used in very, very easy applications that do not require any storage or business rules. Below is a graphical representation of the 2-tier application architecture using MVVM:
When writing a 2-tier application, you only have a business layer (BL) or data access layer (DAL). This architecture is an option if you are writing a very simple application with almost no business rules. In that case, you can simply remove the business layer and handle the business rules in either the Models (DAL) or View-Models.
4.2. 3-tier applications
When applications become more and more complex, users start to demand more functionality and probably business rules. When writing larger applications, it is recommended to write a 3-tier application to separate the business rules from the DAL. Below is a graphical representation on how MVVM fits into the 3-tier architecture:
As you can see, the DAL does not participate in the MVVM at all using a 3-tier application. This is due to the fact that the business layer provides DTO objects that are used as Models, and transforms these DTO objects into entities that the DAL can handle. We see a lot of users referencing the DAL from the UI-layer, but this is wrong. Below is a graphical representation of a good and bad situation of the 3-tier architecture:
An arrow in the graphic above means “uses”.
Good situation
In the good situation, you see that the UI layer uses the BL, and the BL uses the DAL. A top-layer can always use a lower “down-the-hill”. A lower layer may never use a layer above (which is situated in the “very wrong” situation).
Because the DAL is not referenced at all, it is required to create data transfer objects (DTOs) to represent data from the DAL in the BL. The DTO objects are defined inside the BL so the BL is responsible for translating entities from the DAL into DTO objects which are accessible from the UI layer.
Wrong situation
The wrong situation shows a “solution” we see a lot. Developers that use this approach are not aware of the n-tier layers and directly reference the DAL in the UI layer. This way, they don’t have to create custom DTO objects.
If you don’t want to write custom DTO objects, the only option you have is to write a cross-cutting concerns library which can be used by all layers. In the cross-cutting concerns, you can write interfaces for all the entities of the DAL and use these in the BL and UI layer.
Nowadays, most people use ORM mappers. ORM mappers can be used to generate source code for the DAL so you don’t have to spend writing this layer yourself. A tip is to customize the templates for the ORM mapper of your choice (if it is supported by the mapper) so it also generates the DTO objects for you.
Very wrong situation
The very wrong situation shows the three layers of the 3-tier architecture where a user references higher-level layers. This is very bad and destroys the whole separation of concerns (SoC) idea behind the n-tier application architecture. If you think this is right, answer the following question: your BL references the UI in a WPF app, how are you going to use the same BL for a Windows Phone 7 or ASP.NET application?
4.3. MVVM in combination with Silverlight and RIA services
Lots of developers find it hard to find a good way to use MVVM in combination with Silverlight and RIA services. From an architectural point of view, a RIA service does nothing more than provide data in the form of data transfer objects (DTOs). Therefore, a Silverlight application with RIA services must be used in the same manner as the 3-tier architecture described above by using a DTO as the Model.