Showing posts with label software development. Show all posts
Showing posts with label software development. Show all posts

Thursday, January 31, 2013

Data-binding among complex Expressions in C#

What could be more preferable than simply stating X = Y in one place then having the rest of the work transparently handled on your behalf?

Expression trees were one of the many language features introduced with C# 3.0 way back in 2007.  Integration with the compiler allows us to nonchalantly ask it to emit data that represents a line of code instead of going about its usual business of readying the code for execution only.  This leads to a convenient convergence of the benefits of reflection and those of compiler-checked code.  An example that is further described here is that we no longer must use a string literal to meta-identify a property; instead, we can use a lambda expression like o => o.SomeProperty.

It took me much of this month of January 2013 to apply expression trees in a way that goes far beyond that simple property example.  The result demonstrates not only the power of code as data, but also the applicability of the concept of data binding to coding in general instead of in the user-interface alone.

The project arose from the need to manage numerous interdependent properties on view-model and domain model classes.  A property must be updated whenever one of the properties it depends on changes.  Done on an individual bases, this would lead to a lot of event handlers.  My undeviating aim to keep application code as succinct and declarative as possible led me to seek an alternative.  What could be more preferable than simply stating X = Y in one place then having the rest of the work transparently handled on your behalf?  Nothing, of course.  So I create the following public interface and then implemented the guts to make it work:

/// <summary>
/// Keeps a target's properties updated with values determined by corresponding expressions. Properties referenced within a value expression are monitored such that property-change notifications cause the target properties to be updated.
/// </summary>
/// <typeparam name="TTarget">The type of object on which properties will be updated</typeparam>
public class PropertiesUpdater<TTarget> : IDisposable
{
    /// <summary>
    /// Constructs a PropertiesUpdater instance for properties of the specified target.
    /// </summary>
    /// <param name="target">The object on which properties will be updated</param>
    public PropertiesUpdater( TTarget target )
    {
        ...
    }

    /// <summary>
    /// Sets the specified property of target to the result of the specified value expression whenever the value of a property referenced within the value expression changes.
    /// </summary>
    /// <typeparam name="TProperty">The type of the property on target to be set</typeparam>
    /// <param name="targetPropertyExp">The property on target to be set</param>
    /// <param name="valueExp">The expression to be monitored for changes and evaluated as the target property's value</param> 
    /// <returns>The instance on which this method was invoked, to allow multiple invocations to be chained together</returns>
    public PropertiesUpdater<TTarget> AddProperty<TProperty>(
        Expression<Func<TTarget, TProperty>> targetPropertyExp,
        Expression<Func<TProperty>> valueExp )
    {
        ...
    }

    public PropertiesUpdater<TTarget> RemoveProperty<TProperty>(
        Expression<Func<TTarget, TProperty>> targetPropertyExp )
    {
         ...
    }

    public void Dispose()
    {
        ...
    }
}

I will present some usage examples to show the sort of advantage that PropertiesUpdater provides.  The restaurant POS system I am now working on includes a Table domain object that represents the sort of table you sit at.  Table’s OpenOrder property is bound in the user-interface and so its private setter raises a property-changed event for notifying the UI of changes.  Table ’s constructor contains the following code for determining OpenOrder’s value:

new PropertiesUpdater<Table>( this )
    .AddProperty(
        t => t.OpenOrder,
        () => DineInParts.Select( p => p.Owner ).SingleOrDefault( o => o != null && o.IsOpen )
    );

PropertiesUpdater recognizes most LINQ-to-Objects methods and can interpret the lambdas passed to them.  After calling AddProperty in the above example, each of the following causes the target Table.OpenOrder property to be updated on this: (1) changes to the Table.DineInParts collection property’s value on this, (2) adds/removes of the collection instance’s elements, and (3) changes to values of the Owner and IsOpen properties referenced via collection elements.  Under the covers, PropertiesUpdater relies on the referenced objects implementing INotifyPropertyChanged and the referenced collections implementing INotifyCollectionChanged.

Next I will present two usages taken from the constructor of the order detail screen’s view-model in the restaurant POS system-

// Base the phone number and name on their sources in the domain model.
// Initialize these without causing the contact to be overwritten.
new PropertiesUpdater<OrderDetailsScreenPM>( this )
    .AddProperty(
        pm => pm.PhoneNumber,
        () => domainItem.Contact is VerifiedCustomer ? ((VerifiedCustomer)domainItem.Contact).PhoneNumber : null 
    ).AddProperty(
        pm => pm.Name,
        () => domainItem.Contact != null ? domainItem.Contact.Name : null 
    );

// Store a contact in the domain model that has the user-provided phone number and name.
new PropertiesUpdater<Order>( domainItem )
    .AddProperty(
        dm => dm.Contact,
        () => PhoneNumber != null
            // If a phone# is provided then lookup a verified contact; if not found then create one.
            ? (DataAccess.Instance.FindCustomer( PhoneNumber ) ?? new VerifiedCustomer { PhoneNumber = PhoneNumber, Name = Name })
            // If only a name is provided then create an unverified contact.
            : Name != null ? new Customer { Name = Name } : null
    );

The first thing you may notice about this example is that the “one line” permitted for the value expression is actually spanning multiple lines.  The “one line” limit just means the expression must not contain a semicolon.  The expression can in fact be however complex is needed.

In the value expressions for the first instantiated PropertiesUpdater, notice the presence of property paths that navigate across more than one property.  These are domainItem.Contact.PhoneNumber and domainItem.Contact.Name.  What if Contact's value changes?  The former value of Contact is no longer of interest (in particular, PhoneNumber's and Name’s values on the former contact), therefore the PropertiesUpdater stops observing the former contact.  This is a similar situation as when an item is removed from a collection in which case the removed element is no longer observed.  In the opposing case, PropertiesUpdater will begin observing a newly introduced value.

The Wikipedia article on Reactive programming provides a canonical example that is in fact PropertyUpdater’s primary purpose.  So, I decided to call the namespace for holding PropertiesUpdater and its supporting classes “Qnomad.Reactive”, at least until someone who knows better tells me that’s an inappropriate classification.  As for Microsoft’s Reactive Extensions (Rx), I didn’t see its connection to what PropertiesUpdater provides until I came across an interesting article that fills in the gap: Data binding in code using Reactive Extensions.  When I first saw the title, I worried my month-long work on PropertiesUpdater may have been for naught.  The single usage example that the article builds up to, however, falls far short of what PropertiesUpdater can accomplish.  The explained functionality reminds me of the basic building block with which PropertiesUpdater observes referenced objects, which resembles Josh Smith’s PropertyObserver.  Using Rx for this purpose, however, doesn’t seem necessary or even useful.  This leaves me wondering how “reactive” Rx really is; although, I suppose it may just be reactive in a different sense.  As with other CS concepts that become buzzwords, “reactive” is likely to go through a period of overuse before its actual meaning gets whittled down in the minds of the masses.  Instead of waiting for that to happen, though, I would love to hear some clarification sooner.

Realizing the significant time expense of implementing PropertiesUpdater about a week into it, I checked if something similar already exists.  I came across the WhenAny method of the ReactiveUI project, but it pales in comparison to what I ended up accomplishing with PropertiesUpdater.  It wasn’t until after completing PropertiesUpdater and describing it in the above paragraphs that I finally found three projects — Bindable LINQ, Obtics, and Continuous LINQ — that appear to accomplish a similar feat.  My initial impression, however, is that PropertiesUpdater can more easily accomplish the same with its mere two public methods and comparatively tiny implementation.  Anyway, I’ll further explore these two alternatives later, if there is occasion.

Wednesday, December 5, 2012

Collection accessors language feature

Collections are independent types from the domain objects on which they are used to define properties, yet they are usually closely tied to internal business logic of the single domain object that "owns" them.

What do you do in each of the following scenarios:
  1. You have business logic that determines whether or not an item can be added to the collection.
  2. You have some logic that needs to run before an item is added to the collection and another piece of logic that need run after the item was added.
These are the possible approaches that I can think of for tackling these scenarios:
  1. Put that logic in the view-model. The logic will need to be repeated everywhere the collection is modified.
  2. Expose the collection as IEnumerable then add Add/Remove methods directly onto the domain object where you put the check logic. This works but the public collection property can always be cast to ICollection or derivative and directly modified, thus violating the intended encapsulation.
  3. Create a custom collection.
But I do not feel satisfied with any of these options.  I always wished to see a language feature like the add/remove block that was introduced in C# for events but as being available for public collection properties as well.

    public collection IList Details
    {
       add { if (isMaxReached) throw new Exception("max reached"); details.Add(value); }
       remove { details.Remove(value); }
    }

All modifications to the collection would pass through these accessors.

Wednesday, April 13, 2011

Reusable Tree Operations for the .NET Framework

An earlier article of mine describes how a common ITreeNode<T> interface can facilitate reusable tree operations thanks to the introduction of extension methods. That article discusses reusable tree operations with respect to domain-models. Trees, however, are a ubiquitous data structure and also occur throughout the .NET Framework, as discussed in [Eberhardt 2010]. Ideally, the .NET Framework would include an ITreeNode<T> interface that's consistently implemented within the Framework, but this is not so. [Eberhardt 2010] describes a way to provide tree operations to those Framework types by means of the adapter pattern and code generation. His approach, however, has drawbacks. Wrapping a node instance every time it is navigated is likely to impact performance, and relying on code generation complicates maintenance. Upon looking into the matter for myself, I came up with an approach that suffers neither of these drawbacks.

Before continuing onto my solution, I want to note what tree operations, specifically, should be available. Leveraging the functionality already provided by LINQ to Objects reduces this list considerably. For example, instead of numerous methods that deal with ancestors, such as IsAncestorOf and FindAncestorOfType<T>, a single Ancestors method can be provided with LINQ to Objects taking care of the rest.
//item.IsAncestorOf( newParent )
newParent.Ancestors().Contains( item )

//tvi = this.FindAncestorOfType<TreeViewItem>();
tvi = this.Ancestors().OfType<TreeViewItem>().First();
LINQ to XML sets a good example by borrowing its "axis methods" — that query ancestors, siblings, descendants — from XPath. [Eberhardt 2010] does an excellent job of describing these.

Now I will show my solution for adapting .NET Framework tree types in order to make common tree operations available on them. The code that I will be discussing is available as part of Qnomad's CoreHelpers library. To create my solution, I applied a variation of the adapter pattern. Instead of instantiating a wrapper for every tree node, there's just one wrapper per adapted tree type, e.g. DependencyObject. The library also includes a singleton of this sort for the ITreeNode<T> type discussed in my earlier article. The tree operations, then, use the singletons to navigate the hierarchy. The various pieces of this puzzle are outlined below.
  • internal static class TreeOperations: Contains an implementation for each tree operation. Each method signature is of the form:
    internal static IEnumerable<T> Operation<T>( T startNode, ITreeNodeAdapter<T> adapter )
  • internal interface ITreeNodeAdapter<T>
    {
    bool HasSubItems( T treeNode );
    IEnumerable<T> GetSubItems( T treeNode );
    T GetParent( T treeNode );
    }
  • Next come the implementations of ITreeNodeAdapter<T>. The library contains these two:
    • internal class WpfTreeNodeAdapter : ITreeNodeAdapter<DependencyObject>
    • internal class ITreeNodeAdapterImpl<T> : ITreeNodeAdapter<ITreeNode<T>>
You've undoubtedly noticed that everything so far has been declared as internal. The public methods are all on the corresponding "Extensions" classes. The library's WpfExtentions class, for example, contains this method:
  public static IEnumerable<DependencyObject> Ancestors( this DependencyObject startNode )
{
return TreeOperations.Ancestors( startNode, WpfTreeNodeAdapter.Instance );
}
Well, that pretty much wraps it up. So now you see a better way for exposing common tree operations on .NET Framework tree types.

Monday, March 21, 2011

Advantages of the Domain Model

Prior to arriving at my previous consulting assignment, the company had already completed their first WPF project. The architecture they used on that earlier project included a rather unusual, in my opinion, hybrid object/relational in-memory representation of business objects. Some of the business objects were wrapped in View Models, while the View was directly referencing ADO.NET data rows of other business objects. I initially kept an open mind, programming their new app to that earlier architecture. But I eventually realized that it provided me no way to abstract away from the underlying relational structures. I then spent the weekend refactoring the new app, and building its Data Access layer. Having broken away from the status quo established by their first WPF project, however, my efforts were not greeted warmly. I had to spend a subsequent weekend producing the below “Advantages of the Domain Model”, as well as the Microsoft Embraces the Domain Model article I posted earlier, for convincing them to go with a purely object-oriented in-memory representation of business objects.

Advantages of the Domain Model


Confining object/relational mapping logic to a clearly demarcated data access layer (DAL) within your application, facilitates the creation of a single, coherent, object-oriented Domain Model to represent your application’s business objects. Adherence to this practice leads to more robust, scalable, and maintainable software.

Separation of concerns


View
View Model
Domain Model
Data Access
Data Services
Separation of concerns is a fundamental principle within computer science. As applied to an application’s overall architecture, it provides for organizing a complex software system into separate, but interdependent, parts. The new app’s codebase is easier to understand and maintain than the old app, thanks to the separated Data Access, Domain Model, and View Model layers. The responsibilities of all three layers are lumped into one layer within the old app.
  • Conceptual model. The Domain Model provides a concise representation of the domain of interest. This can aid in communication with experts in the problem domain who are not necessarily developers.

  • Division of labor and organization of code. Need to retrieve or persist data? Then call into the DataAccess singleton. Need to execute some business logic when a condition’s selected field changes? Then go to the Domain Model and put the logic into the Condition.SelectedField setter. Need to tell the View how to display itself differently? Then go to the View Model.

  • Code Reuse. Both the old and new apps contain object-relational mapping logic. The difference is that the new app’s Data Access layer, by way of generalized functions, eliminates the needless repetition found within the old app’s numerous Load and Save methods.

  • Consistent interface to in-memory data. Hiding the relational model specifics, as is accomplished by the new app’s Data Access layer, provides a consistent representation of business objects. The View layer in the old app, on the other hand, contains bindings that reference both .NET properties as well as database fields.

  • Maintainability. Because of the separation of responsibility, the new app can be modified more easily when business needs change. Changing a database field’s name, for example, requires a limited maintenance effort in the new app. Since data access is coded concisely in the Data Access layer, it involves altering just one string.

Increased Productivity


Coding directly to ADO.NET objects, as the old app does, means that you cannot easily navigate the relationships between business objects. The new app’s Data Access layer, on the other hand, shields upper layers from database specifics. This allows for more natural modeling of data, and simpler handling of complex relationships between entities.
  • The business objects are strongly typed, so we benefit from compile-time type-checking.

  • Business objects’ members expose themselves through Intellisense, eliminating typos and problems with remembering property names.

  • We can navigate the object-oriented Domain Model by using the OO-dot syntax, such as condition.SelectedField.Type.AvailableOperators. That is, we just choose an object instance to be our point-of-entry, then navigate from there. The ADO.NET objects in the old app, on the other hand, don’t allow you to easily navigate the data model.

Thursday, January 20, 2011

WPF Dialog Service via Binding

View Model logic sometimes involves showing a modal dialog box. The dilemma has always been: how do you show the dialog while abiding by the rule that the View Model not reference the View? A common solution has become to create a dialog service class, then extract its interface for the View Model to consume. In my opinion, using the interface is only slightly better than using the actual class. It still looks to me like the View Model is referencing the View. Why attempt such a charade when the View Model's primary means of communication with the View is perfectly adequate?

Although the View Model must not reference View classes, the View Model can still talk to the View. If there wasn't such a capability, then displaying the View Model's properties to the user would be impossible. The communication method I am referring to, of course, is data binding. Data binding is already the primary means of communication between the View and the View Model. We can use it for showing a dialog box as well.

Showing a dialog box using the solution I have created involves two easy steps:
  1. Add the MessageBoxHelper.Message attached property into the View.
  2. Within the View Model, set the property specified in the first step when you want the dialog box to be shown.
The View Model's property mentioned in these steps is of type DialogPM. This class contains no View-specific logic. It's purpose, rather, is to transport parameters for the MessageBox.Show(... method call from the View Model to the View and, if that method's result is important, back from the View to the View Model.

Download the Qnomad CoreHelpers library to see the complete example.

Sunday, January 2, 2011

Microsoft Embraces the Domain Model

Soon after I introduced a Domain Model into the application I was creating for my employer, I found myself at a team meeting trying to explain to fellow programmers, and my manager at the time in particular, why such a change is beneficial. I started by describing how, by the nature of data flowing from the relational database to the object-oriented runtime environment and back, we have an inherent need to translate between two different data models. The manager stopped me in my tracks when she said that I sounded “too academic”. Although left speechless at the moment, in retrospect (and at the risk of sounding like a smart ass) I should have responded, “the law of gravity may sound academic when described by a physicist, but that alters neither its truth nor practical consequence.” Just as the laws of physics describe our physical world, the world our applications live in can be described in terms of data models. The problem stemming from the presence of two data models, instead of just one, is called the Object-Relational Impedance Mismatch.

The Object-Relational Impedance Mismatch is an “academic” (to quote my former manager) sounding term for a practical problem facing software application development.
…work directly against the relational structure of database tables.

This is all well and good for simple databases and simple applications. However, as a database gets richer and an application more sophisticated, we see increasing divergence between the way an application needs to look at the data—its “conceptual” or “object” model—and the way information is structured in the database—the “storage” or “relational” model.” A manufacturer's ordering system, for example, may store its order information in multiple related tables, yet the application programmer really wants to work with a single, conceptual “order” entity without having to do a complex JOIN in every order-related query. (This is a case of what’s called the “object-relational impedance mismatch,” if you’ve heard that term.)
The above quote is taken from an article in the MSDN Library titled Microsoft Data Development Technologies: Past, Present, and Future by Kraig Brockschmidt and Lorenz Prem, Program Managers at Microsoft.

Microsoft released the ADO.NET Entity Framework in August 2008 as part of the .NET Framework version 3.5 SP1, and then an improved version in the .NET Framework 4 released in April 2010. What is the ADO.NET Entity Framework? From its overview:
The ADO.NET Entity Framework enables developers to create data access applications by programming against a conceptual application model instead of programming directly against a relational storage schema. The goal is to decrease the amount of code and maintenance required for data-oriented applications.
The “conceptual application model” is commonly known as the Domain Model.

With the Entity Framework finally here, it is clear that Microsoft has at long last embraced the Domain Model pattern. This is significant given that, in the 12 year hiatus since Microsoft's last data-access paradigm shift when it released ADO in October 1996, they’ve been careful to find the new emblem of application architecture for years to come. In general, Microsoft is the most immune to “fads”. They tend to do things their own way, and avoid industry standards up until the standards become so engrained that the obvious choice becomes to embrace them or get left behind. Microsoft’s embrace of the Domain Model is evidence, in my eyes, that this has become an engrained industry standard.

For those of us using the .NET Framework to build applications, Microsoft’s commitment to the Domain Model goes beyond confirming an industry standard. Having Visual Studio 2010 installed on our machines, while relying on it so much for development, we also have access to the extensive tooling support Microsoft has built around the pattern. From the MSDN library: “conceptual and relational representations can be easily created using designers in Visual Studio, and the Entity Framework designer in Visual Studio will create a default mapping without any effort on your part.” It’s a safe bet that this tooling support will be continually improved with future Visual Studio releases.

Wednesday, July 1, 2009

DragDropManager for WPF TreeViews and ListViews

Update: Please note that the download for this project has been moved here.

My new drag-and-drop manager for WPF, which handles both TreeViews and ListViews, is ready for download. Here's a list of features it includes:
  • Supports drag-drop operations among any number of TreeViews and/or ListViews.
  • Shows drag adorner while dragging among different TreeViews/ListViews.
  • Explicitly supports two types of drop events: ProcessMove for moving an item, and ProcessLink for linking one (see demo).
  • User controls where, relative to the item under the drag cursor, the item will be dropped: above, below, or (for TreeViews) within.
  • Spiffy animations for grabs, drops, and cancelled operations.
  • Auto-expand item if hovering over it during drag operation.
  • Auto-scroll TreeView or ListView if near top or bottom edge.
  • Works on the standard TreeView and ListView controls. No third-party TreeView or ListView control is required.
  • Not dependent upon a particular presentation-model (aka ViewModel) implementation. The pattern isn't even necessary in order to use the DragDropManager.

Demonstration Application

The demo consists of a TreeView that holds categories, and a ListView populated with the selected category's items. These two controls together have a total of three types of drag-drop operations setup on them.
  1. Move a category within the TreeView
  2. Move an item within the ListView
  3. Link an item with another category
The demo is available for download here. The drag-and-drop setup code in the demo looks like this:

dragMgr.AddControl<Category>( categoriesTreeView );
dragMgr.AddControl<Item>( itemsListView );
dragMgr.AddHandler<Category>( categoriesTreeView, dragMgr_ProcessMove );
dragMgr.AddHandler<Item>( itemsListView, dragMgr_ProcessMove );
dragMgr.AddHandler<Item, Category>( categoriesTreeView, dragMgr_ProcessLink );
dragMgr.GetLinkEffect += dragMgr_GetLinkEffect;

The first two lines indicate which controls will have their dragging managed. The following three lines add the event handlers whose job is to actually move or link the domain-model objects. The last line adds the custom link animations you will see in the demo.

The body of your ProcessMove and ProcessLink event handlers will depend on how you've architected your presentation-model. The demo app doesn't even use one, so the event handlers simply look like this:

void dragMgr_ProcessMove( object sender, MoveArgs<Category> moveArgs )
{
 moveArgs.oldPosition.parent.SubCategories.Remove( moveArgs.itemToMove );
 moveArgs.newPosition.parent.SubCategories.Insert(
  moveArgs.newPosition.childIndex, moveArgs.itemToMove );
}

void dragMgr_ProcessMove( object sender, FlatMoveArgs<Item> moveArgs )
{
 var category = (Category)categoriesTreeView.SelectedItem;
 category.Items.RemoveAt( moveArgs.oldIndex );
 category.Items.Insert( moveArgs.newIndex, moveArgs.itemToMove );
}

void dragMgr_ProcessLink( object sender, LinkArgs<Item, Category> e )
{
 e.TargetLoc.Items.Add( e.ItemToLink );
}

Obfuscation for .NET

Update (1 November 2012):
I recently tried upgrading to the latest Smart Assembly version (now owned by Red Gate) while in the process of upgrading my project to .NET Framework 4.5. The latest Smart Assembly version seemed to work okay at first, but then I discovered a bug that caused it to crash. I sent a bug report to Red Gate, along with a repro, then waited and bugged them until I finally received a reply that said: "I'm hopeful that a release may be available with a couple of weeks, however there's no full time development team currently working on Smartassembly; the majority are deployed on other tools." This was especially infuriating since I had purchased "1 year Support & Upgrades". What kind of support is this? None at all, I think. My conclusion is that development on Smart Assembly is stagnant. Therefore, it's best to consider the product dead.

Original Post:
I recently had to fulfill my need for an obfuscation utility for .NET. More specifically, I needed a solution that works with WPF. I learned that WPF poses a particular challenge concerning obfuscation, since the BAML format has not been made public by Microsoft.

My first attempt was using Dotfuscator Community Edition which comes bundled with Visual Studio. After spending a significant amount of time picking certain properties and methods to exclude, I still couldn't get the obfuscated version of my app to run. So I finally gave up and instead turned to Google to help me find an alternative tool.

The only tool I found, with specific mention of WPF support, was {smartassembly}. As long as I exclude those types and (attached) properties used in XAML, this tool works like a charm.

{smartassembly} projects are stored in an XML format, so you can edit them using either your favorite text editor or {smartassembly}'s designated user-interface. The UI follows a rather interesting concept. It's a gigantic vertically scrollable area, consisting of a collapsible pane for each settings group. It reminds me a lot of a word-processor. This may seem strange at first, but after a couple hours of usage, you'll likely see the design concept's merit points.

{smartassembly} has security and optimization features in addition to simple obfuscation. One of particular interest is error reporting. When your program crashes, error reports can be collected by a server and made available for your viewing. That feature, however, is only available in the Professional and Enterprise editions. The Standard edition will run you 500 USD, and the other editions move up from there. For more information, see the {smartassembly} website.

Wednesday, April 22, 2009

Non-Intrusive Tree & Graph Types

I just submitted a second article to Code Project. This one is called Non-Intrusive Tree & Graph Types. It's an original subject for me, totally different from my first CP article, so I don't know what to expect. I'm looking forward to see what feedback I'll be getting.

Sunday, August 24, 2008

Item Presentation Models for WPF

After two weeks of work (and some play), I've finally posted my Item Presentation Models for WPF article to Code Project. This is my first Code Project article ever, so I'm excited about it. I hope readers find it useful and I look forward to their feedback.

Tuesday, August 19, 2008

Naming domain-specific ItemPresentationModel objects

I've decided to follow a rather unconventional naming pattern for domain-specific presentation-model classes — suffix them with "View". I am aware that this naming breaks away from the conventional terminology of MVC and its derivatives, in which "View" refers to the UI layer. So I devote this blog entry to digressing my reasons.

Outside the scope of MVC-related design patterns, the word "view" has a more general meaning that's applied in varying contexts. SQL, for example, uses it to mean a derived view of base data. Closer to the present topic, WPF includes the CollectionView class which is a sort of presentation-model. People who prefer that "view" strictly refer to the UI probably hate this choice of class name. However, appending "ViewModel" or the even longer "PresentationModel" to all my class names is verbose in my opinion.

For the above reasons I instead use the suffix "View" as an acceptably short alternative for my domain-specific Presentation Model classes. By doing so, I intend to invoke the word's general meaning of the sense that the presentation-model provides a derived view of the domain object. Another interpretation is that the presentation-model provides an interface for the domain object that makes it fit for presentation; the presentation-model is therefore an abstract view (presentation) object. This latter interpretation is useful since it emphasises the presentation-model's actual purpose, which is that it facilitates visual display (in that sense, Josh Smith's original "Presenter" suffix doesn't sound half bad).

I am aware that this naming breaks away from every quasi-standard in the literature of MVC and its derivatives. Even the WPF library doesn't use it consistently. That is, they use the word "View" in its more traditional MVC sense as well, as in ListView and TreeView. If instead WPF named those controls "ListControl" and "TreeControl" — which would be consistent with many other controls in their library such as ContentControl, ItemsControl, UserControl, and TabControl — then I would find their choice of "CollectionView" more acceptable. In any case, I still find their suffix "View" to be so much more aesthetically pleasing than the alternatives, so that's what I choose to use in my own projects. Such a choice, however, has implications only within the scope of individual projects or organisations. Therefore, others can use whatever naming convention they find to be the easiest to live with.

Saturday, May 10, 2008

Revisiting bidirectional association helpers

The one-to-many and many-to-many helper classes in my ObservableCollections project make it easy to maintain in-memory the semantics of bidirectional associations, by keeping an association's references in sync in both directions. The way these helper classes are now, they work only in situations where the many-side is constrained as unique and is non-indexed, i.e. the corresponding collection is an ISet. However, I've encountered a situation in my main project where an association's many-side is indexed, i.e. the corresponding collection is an IList. So I'm revisiting the ObservableCollections project in order to accommodate this need.

Looking back at the bidirectional association helper classes after so much time, I realised how confusing the class and method names have been. So the first step was to rename them. For starters, I renamed the SetContainerToEntityAssocSync class to OneToManyAssocSync to reflect the more general (albeit incomplete Although I will add support to the newly named OneToManyAssocSync class for indexed collections, this more general name isn't completely applicable since I won't be adding support for non-unique collections as well.) desired applicability. And I renamed the SetContainerToSetContainerAssocSync class to ManyToManyAssocSync. After that, in the OneToManyAssocSync class, I changed other occurrences of "setContainer" to say "one" or "oneSide" since it has a multiplicity of one in the relationship. And I changed "entity" to say "many" or "manySide" since it has a multiplicity of n in the relationship. Finally, I renamed some miscellaneous variable names so that they, to, will be consistent with this new terminology.

The next step was to modify the OneToManyAssocSync class's UpdateOneSide method, along with the ManyToManyAssocSync class's UpdateOtherSide method, as follows. The other side's collection must be cast not to ISet, but to the ancestor type ICollection which is common to both ISet and IList. I actually ended up using the generic ICollection<T> since the nongeneric version strangely lacks methods for adding, removing, and checking for containment of items. The code now works in cases the collection type is an IList; however, it only works when the uniqueness constraint is being applied to the IList, which is fine in the case of my main project. It will not, however, work for bags or lists with multiple occurrences of the same item. I included checks for this boundary condition.

Friday, January 18, 2008

Closable TabItem in WPF

Having finally reached the user-interface implementation step in my current programming project, I must first lay the foundation for the program's tabbed document interface (TDI). It's a TDI of the style seen in Firefox and Internet Explorer, where each tab includes it's own close button. Additionally, in my program the set of tabs is fixed and the user can reopen a tab (via a menu) after it's been closed, which makes it appear at its original position. WPF's standard TabItem control doesn't have a close button, so in order to include such a tab in your own program you must find or create a custom control that does the job. You can download the result of my effort—a Visual Studio 2005 solution—here (updated 2008-Feb-11).

The included ClosableTabItem derives from TabItem and provides the functionality you need to easily add close buttons to your program's tabs. The sample application additionally includes for each tab a corresponding item on the 'Tabs' menu, with a check mark indicating the tab's current visibility. After a tab has been closed, a check mark no longer appears on it's menu item. This provides a means for the user to reopen a previously closed tab by selecting a menu item with no check mark. If the user selects a menu item that's currently checked, the item gets unchecked and the tab is closed. But I am not sure this latter behaviour is the most natural/useful. Perhaps it would be better if, rather than closing the tab, it gets selected and it's contents are brought to the front. In that case, I would rename the menu from 'Tabs' to 'Switch Tabs' similar to the 'Switch Windows' menu in Microsoft Word 2007. I am not sure which behaviour would make for a better user experience, so please send me your feedback.

Soon after I started creating the custom control, I came across a blog post which looked like it already did the work for me. Upon looking at the solution's source code, however, I became disappointed with it's architecture. Rather than reusing the Style and Template of it's parent TabItem type by deriving from it, it completely replaces them. This flows contrary to the object-oriented principles of code reuse which I have internalised. So I decided to continue creating my own custom control. At first I thought that after adding the BasedOn attribute onto my custom control's Style element, I'd just need to write a few lines of code then be done with it. But it actually took more work than that, involving WPF features such as data templating, property bindings, and routed commands. The resulting custom style code is a lot shorter than the competition's, though—less than 90 lines as opposed to about 170—so I consider it an improvement.

Thursday, December 6, 2007

Collections for WPF and NHibernate

My current programming project is on the Microsoft .NET platform, and I'm writing code in the C# language. I'm using NHibernate — a popular object/relational mapping tool — in the data access layer, and Windows Presentation Foundation (WPF) for the user interface. One of the features making WPF so attractive is data binding. Although I was initially disappointed when I found out that NHibernate's collections don't work correctly out-of-the-box with WPF data binding, I soon found Gary DeReese's blog entry which provides a (partial) solution. Gary's "NotifyingCollectionDemo" shows how a custom collection type can be built to rectify NHibernate's shortcoming. After studying how his ObservableList (which is actually an observable bag) was created relative to the NHibernate API, I began work on my own "ObservableCollections" project which includes three custom collection types: observable bag, observable list, and observable set.

I've finished creating these custom collection types, so you can download the result now (updated 2008-Dec-10) to use in your own projects. The zip archive contains a Visual Studio 2005 solution that includes three projects. The "ObservableCollections" project is the library containing the custom collections. The "ObservableCollections Demo" project is a WPF program that you can run to play with the contents of a sample set and sample list collection. And the "CoreHelpers" project contains some miscellaneous helper classes that I use in various projects. Before running the demo project, however, you'll need to do the following:
  • Add references to the library and demo projects, pointing to the following NHibernate assemblies on your computer (unless already in the GAC): NHibernate, Castle.DynamicProxy, Iesi.Collections, and log4net.

  • Change the absolute path of the database in the hibernate.cfg.xml file to match its location on your computer.
The "CoreHelpers" project includes a OneToManyAssocSync helper class that makes it easy to maintain in-memory the semantics of a one-to-many bidirectional association. The demo project shows how to use it. There is also a ManyToManyAssocSync class for easily maintaining many-to-many bidirectional associations. (See this blog entry for a note about the renaming of these classes from their former names.)