To property, or not to property?
I am trying to figure out what would give me the nicest code. Which is a little subjective of course, I realize.
I have an application that accesses a database for which I have written an assembly that hides details about this database from all the applications that make use of this assembly.
I also have an WPF applicat开发者_JAVA技巧ion that makes use of this assembly to display various cost calculations in which I would like to use databinding.
Databinding is only possible to properties of objects (as far as I got to work). This would mean I would need an object, preferably with INotify support and a range of objects. However, I would prefer to keep INotify and WPF things outside the assembly that handles database access.
How do others solve this: Keep WPF things outside the database layer (such as INotify) and inside your WPF allow binding? Write a wrapper? Or do most people put a 'property'/'INotify' class as data transfer object directly into the database layer?
Other people solve this by implementing the MVVM design pattern.
You are laboring under a misconception. INotifyPropertyChanged
is not a WPF thing. Consider:
- It is part of
System.dll
- It is in the
System.ComponentModel
namespace - It has been part of in NET Framework since version 2.0
- It is supported by most NET Framework data objects out of the box including ADO.NET's
DataRowView
and ComponentModel'sObservableCollection
. - It is automaticaly used by WinForms, ASP.NET, WPF, and many third-party packages for interfacing with data objects.
Since all the automatically-generated data layers Microsoft produces implement INotifyPropertyChanged
, why should you treat your data layer any differently? Obviously your data layer needs to notify its clients somehow when properties change. Why not use NET Framework's built-in mechanism?
In my opinion any data layer containing mutable objects should implement property change notifications as a matter of course. INotifyPropertyChanged
was designed to be such a notification mechanism, so why not use it as it was intended?
On a more general note: Adding an extra wrapper layer is generally just inefficient code bloat. Sometimes it is necessary and even beneficial, but don't do it just for the sake of doing it. Many times reasonably designed data layer objects work very well as view models. Only where your view model diverges from your data layer or where you need additional functionality should you consider introducing extra complexity, and then only on a case-by-case basis.
I think the cleanest solution is to write a wrapper object in your WPF assembly and keep the INotify
types out of the database assembly. There is no reason to add the complication of INotify
to the database layer unless it provides a specific advantage.
Write a wrapper. If the wrapping is pretty straight-forward you could even build a generator to generate all classes based on the source DTO's
You might look into PostSharp, this is just the kind of thing Aspect Oriented Programming (AOP) is for. There are a lot of examples weaving INotify* into model classes. I haven't started using PostSharp on a real project yet but it's looked promising in some test scenarios we've tried it on.
One more thing to note that's useful - if you know that the property you're binding to is immutable (i.e. a singleton object or something that'll be initialized once and never touched), you don't need to make it INotifyPropertyChanged - a simple property will work fine.
精彩评论