Had a great time at MDC 2012 for those who had problems getting my presentation files you can get them here.
I have included the .bak for the pitty love database as well.
Enjoy,
Brette
Had a great time at MDC 2012 for those who had problems getting my presentation files you can get them here.
I have included the .bak for the pitty love database as well.
Enjoy,
Brette
Last year around October I decided to finally attend my first TechMasters meeting. It had been something I had thought about for a few years but I just never pulled the trigger. But one Tuesday morning last October I got myself up a bit earlier and headed out to the Benchmark Learning Building where we host our weekly meetings. Knowing absolutely nothing about Toastmasters and even less about TechMasters I had no idea what to expect. But what I did know is that I had several things I wanted to improve upon personally. As a software developer for 10+ years I had become fairly comfortable with my technical skills. My communication skills however, like many of us technical types had a lot of room for improvement.
At my first meeting I was given a warm greeting from the regular members, so much so that I came back the next week and signed up. After just 6 months of attending regular meetings I can honestly say that my presentation skills have very much improved. I have spoken at my first user group, and am hoping to be speaking at the upcoming Microsoft Developer Conference. While these skills are always a work in progress and I am a long way from where I hope to be in the future, I feel like I now at least have tools at my disposal to help me communicate more effectively than before I started. These tools do not just apply to presentations, but also when communicating with people one on one or in small groups. TechMasters gives you weekly practice at impromptu speaking, listening, public speaking, and even delivering jokes to a group in a fun and friendly environment. And these skill are useful in every aspect of your life.
So why the blog post? Well it’s simple, I think its a great thing and would like to see more of the local technical folks show up. I know mornings are hard, but guess what? Now you have a chance to check it out after work. This month on April 24th we are launching the TechMasters After Dark Series. A free event where you can see some of our speakers in action. This month one of our most veteran members Paul Scivetti will be delivering a presentation on how to give presentations! Paul is a very dynamic speaker who regularly speaks at the local user groups and the like. Not only is Paul a great speaker, I was lucky enough to have him as my mentor when I joined (we have a mentoring program). And as such I can tell you from personal experience he has a lot of great information to share on the topic of presenting.
So if you are like I was, and have always been curious but just never made it to a morning meeting here is your chance!
Hope to see you there!
Brette
To access the code discussed in this post click here. Feel free to do what you want with it. Though no warranty for you.
Commanding is a pretty amazing thing, and in WPF it is about as good as it gets. But as with all things cool, design decisions need to be made when considering their usage in an application. One such decision that I have had to make several times is how to best deal with core application commands such as the SaveCommand and CloseCommand. These global application commands are particularly tricky for a few reasons. First, you must ensure consistent behavior throughout the entire application. It is important that users do not have to relearn these commands on each screen the navigate to. Secondly and equally important, the development experience must be simple enough that the first point can be realized. These type of application commands all share three important traits.
Over time I have started to use the term Contextual Commands when describing these types of commands. In this post I will outline the approach that I have used with success on a few different projects as well as provide a simple reference implementation. But before that, let us outline what each of the three traits listed above mean.
Accessibility is a primary trait that Contextual Commands must have. This simply means that commands are presented to the user and executed by the user in a similar fashion throughout the entire application. A good example of this is how Microsoft Word handles the Save command. Several consistent options exists.
In fact users have become so conditioned to this commands that many will hit control+s as part of their normal key press behavior, allowing them to save their work as they go.
To accomplish Accessibility in a developer friendly way I choose to make all contextual commands singletons. (Take a deep breath, I know, I know). Utilizing the Singleton Pattern in this case frees developers from the pain of creating instances, command bindings, and all the other error prone work that would need to be done otherwise. Making Contextual Commands singletons allows us to expose commands in multiple ways while ensuring the basic buildup of a command will remain consistent. In short all visualizations of a Contextual Command use the same instance limiting its possible variation that could hurt overall usability.
Predictability means that aside from contextual differences, the execution of a command will behave in the same way every time it is executed. For example if you decide the Save button will be disabled until a view is dirty that choice should hold true throughout all views. If you decide that your close command is going to prompt users for unsaved changes we need to make sure it always does. There should be no variation in overall experience of using these commands. Holding to the standard of predictability will ensure that developers need not worry about such choices preventing them from mucking up your beautiful framework code.
To accomplish Predictablility base implementations of each command will be provided. Using a combination of the Tempalate Method and Provider Pattern we can open the implementation of the command enough to developers so contextual differences can be supported yet at the same time closing off its core implementation ensuring its execution is predictable every time. Textbook Open Closed Principle.
The last and most important point is that these commands must consider the current context of the application. For example clicking the save button in Microsoft Word it saves the document that is currently in view. This may seem simple, but often times this simple concept turns into some very nasty error prone code. Think about what it means to save a document. To save the document correctly there are several things that need to be considered. Is the file readonly? Is the file on a network share? Is the file in collaboration mode? Is the file a word document? Is it a html document? All of these decisions are contextual in nature and will likely differ on each view in an application.
Gathering enough context to correctly save something can often times be a lot of work. Using the Provider Pattern helps us keep this code encapsulated and clean. Each view/control will have a chance to provide to the commands the contextual details needed to handle the difference present in each view.
As usual, the reference implementation I am providing here is illustrative at best. There are many things that should be done differently in a real application.
A few months ago I posted my flavor of the RelayCommand . RelayCommand is a simple implementation of the ICommand interface adding to it support for asynchronous processing, Predicates and Actions, as well BusyCursor support. Also for simplicity I usually group all Contextual Commands in a single class called ContextualCommands. If you prefer a more granular approach you could split this class apart into several separate classes, I will leave that up to you . Lets take a quick look at components needed to support the implementation. The image blow shows the core components of our the setup.
The IContextualCommands interface simply defines the commands I consider contextual (CloseCommand, SaveCommand). In addition to defining the commands this interface defines the SetProvider method. This method gives consumers the ability to change the command provider that is used for each of the command implementations. In the end it is the SetProvider that allows individual views to provide the contextual information needed by the commands. The SetProvider method will work with the IContextualCommandsProvider interface.
The IContextualCommandsProvider interface defines the methods each provider must implement. Since I have lumped the ContextualCommands into a single class the provider must provide the details for each command. The implementation provided by the provider will be used during command execution this is the key to supplying contextual differences from view to view.
</pre> using System.Windows.Input; namespace ProviderBasedCommands.Framework { /// <summary> /// Interface for our Contextual Commands /// </summary> public interface IContextualCommands { /// <summary> /// Gets the save command. /// </summary> /// <value>The save command.</value> ICommand SaveCommand { get; } /// <summary> /// Gets the close command. /// </summary> /// <value>The close command.</value> ICommand CloseCommand { get; } /// <summary> /// Sets the provider for the contextual commands. /// </summary> /// <param name="contextualCommandsProvider">The contextual commands provider.</param> void SetProvider(IContextualCommandsProvider contextualCommandsProvider); /// <summary> /// Determines whether this instance [can close command execute] the specified param. /// </summary> /// <param name="param">The param.</param> /// <returns> /// <c>true</c> if this instance [can close command execute] the specified param; otherwise, <c>false</c>. /// </returns> bool CanCloseCommandExecute(object param); /// <summary> /// Closes the command executed. /// </summary> /// <param name="param">The param.</param> void CloseCommandExecuted(object param); /// <summary> /// Determines whether this instance [can save command execute] the specified param. /// </summary> /// <param name="param">The param.</param> /// <returns> /// <c>true</c> if this instance [can save command execute] the specified param; otherwise, <c>false</c>. /// </returns> bool CanSaveCommandExecute(object param); /// <summary> /// Saves the command executed. /// </summary> /// <param name="param">The param.</param> void SaveCommandExecuted(object param); } } <pre>
</pre> namespace ProviderBasedCommands.Framework { public interface IContextualCommandsProvider { /// <summary> /// Determines whether this instance [can close command execute] the specified param. /// </summary> /// <param name="param">The param.</param> /// <returns> /// <c>true</c> if this instance [can close command execute] the specified param; otherwise, <c>false</c>. /// </returns> bool CanCloseCommandExecute(object param); /// <summary> /// Closes the command executed. /// </summary> /// <param name="param">The param.</param> void CloseCommandExecuted(object param); /// <summary> /// Determines whether this instance [can close command execute] the specified param. /// </summary> /// <param name="param">The param.</param> /// <returns> /// <c>true</c> if this instance [can close command execute] the specified param; otherwise, <c>false</c>. /// </returns> bool CanSaveCommandExecute(object param); /// <summary> /// Closes the command executed. /// </summary> /// <param name="param">The param.</param> void SaveCommandExecuted(object param); } } <pre>
The ContextualCommands class is the single implementation of the IContextualCommands interface and is registered with Unity as a singleton. This class exposes the Contextual Commands to the rest of the application. This class does a few important things for us.
</pre> using System.Windows; using System.Windows.Input; using ProviderBasedCommands.Command; namespace ProviderBasedCommands.Framework { public class ContextualCommands : IContextualCommands { #region Private Data Members /// <summary> /// Close Command Input Key Binding /// </summary> private readonly InputBinding _closeCommandInputBinding; /// <summary> /// Save Command Input Key Binding /// </summary> private readonly InputBinding _saveCommandInputBinding; /// <summary> /// Current provider for command implementations /// </summary> private IContextualCommandsProvider _contextualCommandsProvider; #endregion #region Constructor /// <summary> /// Initializes a new instance of the <see cref="ContextualCommands"/> class. /// </summary> public ContextualCommands() { //Create the actual command instances and related key bindings CloseCommand = new RelayCommand(CanCloseCommandExecute, CloseCommandExecuted); _closeCommandInputBinding = new KeyBinding(CloseCommand, Key.Escape, ModifierKeys.None); SaveCommand = new RelayCommand(CanSaveCommandExecute, SaveCommandExecuted); _saveCommandInputBinding = new KeyBinding(SaveCommand, Key.S, ModifierKeys.Control); } #endregion #region IContextualCommands Members /// <summary> /// Gets the save command. /// </summary> /// <value>The save command.</value> public ICommand SaveCommand { get; private set; } /// <summary> /// Gets the close command. /// </summary> /// <value>The close command.</value> public ICommand CloseCommand { get; private set; } /// <summary> /// Sets the provider for the contextual commands. /// </summary> /// <param name="contextualCommandsProvider">The contextual commands provider.</param> public void SetProvider(IContextualCommandsProvider contextualCommandsProvider) { //Set provider _contextualCommandsProvider = contextualCommandsProvider; //If null lets clear the key bindings if (contextualCommandsProvider == null) { RemoveKeyBindings(); } RegisterKeyBindings(); } /// <summary> /// Determines whether this instance [can close command execute] the specified param. /// </summary> /// <param name="param">The param.</param> /// <returns> /// <c>true</c> if this instance [can close command execute] the specified param; otherwise, <c>false</c>. /// </returns> public bool CanCloseCommandExecute(object param) { if (_contextualCommandsProvider == null) { return false; } return _contextualCommandsProvider.CanCloseCommandExecute(param); } /// <summary> /// Closes the command executed. /// </summary> /// <param name="param">The param.</param> public void CloseCommandExecuted(object param) { if (_contextualCommandsProvider != null) { _contextualCommandsProvider.CloseCommandExecuted(param); } } public bool CanSaveCommandExecute(object param) { if (_contextualCommandsProvider == null) { return false; } return _contextualCommandsProvider.CanSaveCommandExecute(param); } /// <summary> /// Saves the command executed. /// </summary> /// <param name="param">The param.</param> public void SaveCommandExecuted(object param) { if (_contextualCommandsProvider != null) { _contextualCommandsProvider.SaveCommandExecuted(param); } } #endregion #region Private Methods /// <summary> /// Registers the key bindings. /// </summary> private void RegisterKeyBindings() { if (!Application.Current.MainWindow.InputBindings.Contains(_closeCommandInputBinding)) { Application.Current.MainWindow.InputBindings.Add(_closeCommandInputBinding); } if (!Application.Current.MainWindow.InputBindings.Contains(_saveCommandInputBinding)) { Application.Current.MainWindow.InputBindings.Add(_saveCommandInputBinding); } } /// <summary> /// Removes the key bindings. /// </summary> private void RemoveKeyBindings() { Application.Current.MainWindow.InputBindings.Add(new KeyBinding(CloseCommand, Key.Escape, ModifierKeys.None)); Application.Current.MainWindow.InputBindings.Add(new KeyBinding(SaveCommand, Key.S, ModifierKeys.Control)); } #endregion } } <pre>
With the basic components built out a discussion about their usage may be helpful before you look at the example code. Since the ContextualCommands class is a singleton the only moving part is the underlying provider implementation. Generally speaking the ContextualCommands class is supplied with a new provider each time a view is presented. In the example code you will notice I include a simple Controller object. This class is responsible for presenting views into the MainRegion of our application. Essentially when the Controller class is asked to present a view the following things happen.
</pre> using Microsoft.Practices.Unity; namespace ProviderBasedCommands.Framework { /// <summary> /// Controller used to present and close views /// </summary> public class Controller : IController { #region Dependency /// <summary> /// Gets or sets the container. /// </summary> /// <value> /// The container. /// </value> [Dependency] public IUnityContainer Container { get; set; } /// <summary> /// Gets or sets the region manager. /// </summary> /// <value> /// The region manager. /// </value> [Dependency] public IRegionManager RegionManager { get; set; } /// <summary> /// Gets or sets the contextual commands. /// </summary> /// <value>The contextual commands.</value> [Dependency] public IContextualCommands ContextualCommands { get; set; } #endregion #region IController Members /// <summary> /// Presents the dialog. /// </summary> /// <typeparam name="T"></typeparam> public void PresentDialog<T>() where T : IDialog { RegionManager.ApplyDialogSettings(null); RegionManager.DialogRegion.Content = Container.Resolve<T>(); RegionManager.DialogRegion.ShowDialog(); } /// <summary> /// Closes the view. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="view">The view.</param> /// <returns></returns> public bool CloseView<T>(T view) where T : IView<IViewModel> { RegionManager.MainRegion.Content = null; ClearCommandProviders(view); return true; } /// <summary> /// Presents the view. /// </summary> /// <typeparam name="T"></typeparam> public void PresentView<T>() where T : IView<IViewModel> { var view = Container.Resolve<T>(); SetViewAsCommandProvider(view); RegionManager.MainRegion.Content = view; } /// <summary> /// Presents the view. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dialogSettings">The dialog settings.</param> public void PresentDialog<T>(DialogSettings dialogSettings) where T : IDialog { RegionManager.ApplyDialogSettings(dialogSettings); RegionManager.DialogRegion.Content = Container.Resolve<T>(); RegionManager.DialogRegion.ShowDialog(); } #endregion #region Private Methods /// <summary> /// Changes the command providers. /// </summary> /// <param name="view">The view.</param> private void SetViewAsCommandProvider(IView<IViewModel> view) { var contextualCommandProvider = view.ViewModel as IContextualCommandsProvider; if (contextualCommandProvider != null) { ContextualCommands.SetProvider(contextualCommandProvider); } } /// <summary> /// Changes the command providers. /// </summary> /// <param name="view">The view.</param> private void ClearCommandProviders(IView<IViewModel> view) { var contextualCommandProvider = view.ViewModel as IContextualCommandsProvider; if (contextualCommandProvider != null) { ContextualCommands.SetProvider(null); } } #endregion } } <pre>
In short, every time a view is presented that view becomes the provider to the ContextualCommands.
In real life not all ViewModels would implement the IContextualCommandsProvider interface. This puts us in a tricky position when the current ViewModel implements the interface, and the ViewModel we are navigating to does not. Since the new ViewModel is not a provider the Controller will not call the SetProvider as a result the last ViewModel will remain the provider. This can lead to memory leaks, and all sorts of strange things. To get around the disconnect the SetProvider method allow nulls to be passed in. This essentially disables all of the ContextualCommands. This problem would best be solved with the creation of a NullProvider type but for simplicity I have ignored that fact.
I created a very small sample implementation of this concept. To download it click here. This application contains the following things.
Please feel free to download the code and sort through all the details yourself, my intent with this post is simply to introduce the concept of Provider Based Commands. I hope the example code is clear enough to show you the power of this approach. I can tell you from personal experience, every time I go to a new client this is one of the first things I implement. And time and time again, I am happy I did it this way.
Enjoy!
Often times you need to be able to take action on an entire object graph, or specific types in a graph. An example of this could be walking the graph and setting a single property on all of your business objects. Perhaps a bool indicating the state of an object like IsDirty. Well since graphs are all different shapes a handy way to do this is through c# iterators. The idea being you supply a root object and the type of object you want to deal with. The method will then return to you each instance of said type.
There are a couple of things we want to do with this implementation.
Lets take a look at how this might work.
public static class ObjectExtensions { /// <summary> /// Finds all object of the supplect type parameter. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj">The obj.</param> /// <param name="exclusionTypes">The exclusion types.</param> /// <returns></returns> public static IEnumerable<T> FindAll<T>(this object obj, params Type[] exclusionTypes) where T : class { if (obj is T) { yield return (obj as T); } var collection = obj as ICollection; if (collection != null) { foreach (var item in collection) { foreach (var child in FindAll<T>(item, exclusionTypes)) { yield return child; } } } else { foreach (var property in obj.GetType().GetProperties().Where(item => !IsTypeExcluded(item.PropertyType, exclusionTypes))) { var propertyValue = property.GetValue(obj, null); if (propertyValue != null) { foreach (var item in FindAll<T>(propertyValue, exclusionTypes)) { yield return item; } } } } } /// <summary> /// Determines whether [is type excluded] [the specified type]. /// </summary> /// <param name="type">The type.</param> /// <param name="exclusionTypes">The exclusion types.</param> /// <returns> /// <c>true</c> if [is type excluded] [the specified type]; otherwise, <c>false</c>. /// </returns> private static bool IsTypeExcluded(Type type, params Type[] exclusionTypes) { if (type == typeof(string) || type.IsValueType) { return true; } if (exclusionTypes != null && exclusionTypes.Length > 0) { if (exclusionTypes.Contains(type)) { return true; } } return false; } }
Lets look at its usage.
class Program { static void Main(string[] args) { var cat = new cat { Name = "Test", Arms = new List<Arm> { new Arm { FingerCount = 10 } }, Legs = new List<Leg> { new Leg { Size = 300 } } }; var x = cat.FindAll<Arm>().ToList(); Console.Read(); } } public class cat { public string Name { get; set; } public List<Leg> Legs { get; set; } public List<Arm> Arms { get; set; } } public class Leg { public int Size { get; set; } } public class Arm { public int FingerCount { get; set; } }
Enjoy!
First thing first I want to point out that there are many implementations of the Relay/Delegate command out there to choose from. My two personal favorites are Josh Smiths RelayCommand and of course the DelegateCommand from the Prism Library. That said, both of them miss things that many of my projects have required and as a result I have had to either extend, or roll my own. So in this post I am going to add to the mix yet another implementation. I presented this implementation earlier this month as part of my MVVM discussion with the folks at the Mankato .Net User Group and a few people afterwards asked me about it so I have decided to make it public.
Use it if like or take and change it so it fits your needs more appropriately. Either way no warranty for you!
Relay commands are very basic implementations of the ICommand interface. WPF people may say what about RoutedCommand? Well, there are several reasons you don’t want to use RoutedCommands in our ViewModels, the most obvious is because they route! Aside from that they rely on the creation of a CommandBinding, and at the end of the day it’s just not real clean.
RelayCommand makes it very easy for our ViewModels to create command instances that our Views can bind to. At the same time RelayCommand with its delegate support allows our ViewModels to control the command implementation details. This helps make our code more testable, and limits the command class explosion that happens if you start creating a class for each command.
So what do I want my RelayCommand to do? Below is a list of features that are not native to many other implementations that I find I cannot live without.
So let’s take a look at the code that accomplishes this.
using System; using System.Threading.Tasks; using System.Windows.Input; namespace Commanding { public class RelayCommand : ICommand { #region Private Data Members /// <summary> /// Flag indicates that the command should be run on a seperate thread /// </summary> private readonly bool mRunOnBackGroudThread; /// <summary> /// Predicate that that evaluates if this command can be executed /// </summary> private readonly Predicate<object> mCanExecutePredicate; /// <summary> /// Action to be taken when this command is executed /// </summary> private readonly Action<object> mExecuteAction; /// <summary> /// Run when action method is complete and run on a seperate thread /// </summary> private readonly Action<object> mExecuteActionComplete; #endregion #region Constructor /// <summary> /// Initializes a new instance of the <see cref="RelayCommand"/> class. /// </summary> /// <param name="canExecutePredicate">The can execute predicate.</param> /// <param name="executeAction">The execute action.</param> /// <param name="executeActionComplete">The execute action complete.</param> public RelayCommand(Predicate<object> canExecutePredicate, Action<object> executeAction, Action<object> executeActionComplete) : this(canExecutePredicate, executeAction, true) { if (executeActionComplete == null) { throw new ArgumentNullException("executeActionComplete"); } mExecuteActionComplete = executeActionComplete; } /// <summary> /// Initializes a new instance of the <see cref="RelayCommand"/> class. /// </summary> /// <param name="canExecutePredicate">The can execute predicate.</param> /// <param name="executeAction">The execute action.</param> /// <param name="runOnBackGroundTread">if set to <c>true</c> [run on back ground tread].</param> public RelayCommand(Predicate<object> canExecutePredicate, Action<object> executeAction, bool runOnBackGroundTread) : this(canExecutePredicate, executeAction) { mRunOnBackGroudThread = runOnBackGroundTread; } /// <summary> /// Initializes a new instance of the <see cref="RelayCommand"/> class. /// </summary> /// <param name="canExecutePredicate">The can execute predicate.</param> /// <param name="executeAction">The execute action.</param> public RelayCommand(Predicate<object> canExecutePredicate, Action<object> executeAction) { if (canExecutePredicate == null) { throw new ArgumentNullException("canExecutePredicate"); } if (executeAction == null) { throw new ArgumentNullException("executeAction"); } mCanExecutePredicate = canExecutePredicate; mExecuteAction = executeAction; } /// <summary> /// Initializes a new instance of the <see cref="RelayCommand"/> class. /// </summary> /// <param name="executeAction">The execute action.</param> public RelayCommand(Action<object> executeAction) : this(n => true, executeAction) { } #endregion #region ICommand Members /// <summary> /// Occurs when changes occur that affect whether or not the command should execute. /// </summary> public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } /// <summary> /// Defines the method that determines whether the command can execute in its current state. /// </summary> /// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param> /// <returns> /// true if this command can be executed; otherwise, false. /// </returns> public bool CanExecute(object parameter) { return mCanExecutePredicate(parameter); } /// <summary> /// Defines the method to be called when the command is invoked. /// </summary> /// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param> public void Execute(object parameter) { using (new BusyCursor()) { if (!mRunOnBackGroudThread) { mExecuteAction(parameter); } else { if (mExecuteActionComplete != null) { //Run with continuation var context = TaskScheduler.FromCurrentSynchronizationContext(); Task.Factory.StartNew(mExecuteAction, parameter).ContinueWith(mExecuteActionComplete, context); } else { //Run as fire and forget Task.Factory.StartNew(mExecuteAction, parameter); } } } } #endregion } }
There are several overloaded constructors for this class; each of them implies how the command should behave (Sync or Async). This allows our ViewModels to dictate how these commands should function upon construction time.
One of the core goals of an implementation like this it to allow the details of each command to remain in our ViewModels, the Predicate, and Action delegates help us with this quite nicely. Making the parameters to these delegates generic could make this even more flexible but the this example I have left that out.
Looking at the CanExecuteChanged event, notice how the CommandManager.RequestSuggested event is being wrapped. This is very nice because we put the burden of raising the CanExecuteChagned event on the shoulders of WPF. Additionally the RequestSuggested event is static so it will only hold onto our handlers as a weak reference, so we are good from a memory leak perspective.
The magic all comes together here, some simple logic to determine how the supplied Action delegate will be executed. Maybe it’s synchronous (with a busy cursor) maybe it’s asynchronous. Maybe a callback is executed once the work put on a separate thread is complete, maybe its fire and forget. All this goodness is dependent on the constructor you decided to call when you created your instance.
So while not earth shattering, this is the implementation (or a slight variance of it) that I use in most of my WPF projects. The command supports the provider concept by using delegates, sync and async processing, and leverages the command manager to raise the CanExecuteChanged event handler in a memory safe way. Hopefully you will get some use out of this.
The year was 2010 and the location was Botswana Africa inside a wild game reserve just south of the Zimbabwe border. I was walking back to our camp site from the showers wearing only the towel around my waist when I inadvertently crossed paths with a monkey that was tending to her young. Unhappy with my presence she lunged at me chasing me back into the shower area. As I stared at the hissing monkey now blocking my exit I began frantically calculating my options.
It was at this point I asked myself how on earth did I get end up here?
To answer that question I have to go back to 8th grade when my parents reluctantly purchased me my first guitar. I say reluctantly because my general pattern was to lose interest in everything I started very quickly. This was not the case with guitar however. I became obsessed with it; at school I joined the Jazz band, outside of school I played in rock bands, I started taking lessons two times a week, and even started to learn how to build them.
It was my obsession with guitar that led me to college. Mostly interested in Classical guitar by this time, I enrolled at the University of River Falls, while a school mostly known for agriculture they also have one of the best classical guitar instructors in the Midwest. Music became my life, six hour days in the practice rooms, music theory parties, composition contests it was a great time in my life.
About two years into my study, my guitar teacher expressed interest in developing a web site for his group the Minneapolis Guitar Quartet. Knowing absolutely nothing about computing at that time and even less about web development I volunteered to do it. Using my roommate’s computer and a HTML book from the computer science department’s library I built my first website. It was at this point that I found yet another obsession. Programming! Shortly after that I added an additional major in computer science. This was the happiest day of dad’s life, since he had hopes that I could actually get a job after college.
Fast forward 4 years, with my music degree and computer science degree in hand, I found myself in Winona, MN working as a web developer for a company called Fastenal. It was here where I met a woman from India name Pragya who after several months of begging finally agreed to go out on a date with me. While it’s true I begged for the first date, I want to make sure to state that it was her who asked me to marry her! In 2005 Pragya and I were married in New Delhi India, in a traditional Hindu wedding.
By now you must be thinking, what does this all have to do with the Monkey? I promise I am getting there!
When my wife came to Iowa for college her parents left India to start a manufacturing company in Africa. With half of her family in India and her parents in Africa we travel to both places quite a bit. In 2010 we went to Africa, and traveled to the Chobe game reserve for a safari, and this is where I found myself face to face with the angry monkey.
So how did I get here? My parents got me a guitar, guitar led me to college, college let me to computing, computing led me to Pragya, and Pragya let me to Africa and Africa to this very angry monkey.
So what happened? Well just as the monkey was about to lunge at me, out of nowhere a man with a big broom smacked the monkey out of the door way. The man started at me and said, “Don’t play with the monkeys”
An interesting thing happened to me a few years back while sitting in a Sprint Retrospective. A nameless developer on our team voiced some frustration with our UI Framework. Person X stated that that the UI Framework was too constraining. Since I was largely responsible for this aspect of the system I was interested in hearing the developers concerns. When pressed to describe the areas Person X felt were too limiting, it became clear that the developer was trying to work out of band and out of pattern. The developer was trying to introduce a new UI pattern not yet discussed or agreed upon by our team and users. It was in this moment it occurred to me that while frameworks need to support the needs of the system, they should also prevent developers from introducing things that are not well understood at a whim. This particular conversation was the seedling for my particular view of how frameworks should support applications. I call it Framework Organics.
This question will likely elicit 10 different answers if you ask 10 different people. And though you did not ask here is my answer.
A framework should box developers into the understood and agreed upon patterns while allowing for the necessary changes agreed upon over time.
In greater detail a framework should provide support for concepts that are relevant to the system being developed. In stark contrast a framework absolutely should not support any random concept a developer can dream up. It should limit the ability of developers to travel to far off into the weeds. Protecting your users from cowboy coders who are spinner happy!
Along with limiting developers from introducing new concepts, a well-designed framework should be able to adapt to change over time. It should be resilient and extendable to meet any reasonable need that may arise throughout the development lifecycle. This does not mean that you need to build an over engineered goliath of a framework that supports every possible permutation possible. Because you can’t and no one I have ever met can.
One of my favorite economists F.A. Hayek wrote an entire book called ‘The Fatal Conceit’. In this book he makes the case against socialism. Political affiliation aside his premise is worth mentioning here. Hayek believed as many Austrian Economists did/do, that it was impossible for central planners to understand that millions of interactions of the millions of people they govern. He also argued that any attempt to plan around these interactions was a form of conceit that was doomed to fail. Austrians believe that the framework of society was grown overtime in a free market sort of way. If problems came up they were addressed and solved, it was this sort organic evolution that Austrians feel allow us to strive as we do today.
Again this is not meant to be a political rant. But parallels can be drawn between concepts in software design and economics. The Agile Method and the various approaches of iterative development it has spawned clearly harness the power of organic growth over time. Short cycles of problem/solution/repeat are much more in line with Hayek’s ideas than they are with say the Keynesian approach to planned government. In contrast the Waterfall methodology is more in line with Socialism. Waterfall is far more plan centric it’s ridged, and less adaptable to change over time. Waterfall does what it can to make sure change is as painful and costly as possible. It’s no wonder at all why that methodology is for the most part dead.
Ok so I am not an economist and I really do not want to be tagged a right wing radical because of this post. But the point here is simple, frameworks should evolve organically overtime. Yes this means constant refactoring of your core code throughout the life of a project. When new patterns are introduced, your framework will change and code sweeps will need to happen. As your product grows so will the level of support your framework provides but on an as needed basis. Keeping in mind the framework should also limit developers to the current set of patterns that are supported by the current revision of your framework.
The benefit of framework limitation should not be underestimated. By limiting concepts allowed in your systems users start to learn and understand stereotypes. As a result new screens seem familiar to them, less support questions arise, and your application is usable unlike ITunes for the PC. The benefits are not only seen by users. Developers now have a common language when designing new screens. “This fits our Master Detail pattern”; “This fits our search pattern”. And if a scenario does not seem to fit existing patterns perhaps the introduction of something new is needed. And the cycle continues in a nice organic sort of way!
Enjoy
I Got the chance to look at the FluentValidation.Net Framework this week. Overall its pretty spiffy! The API seems to handle most validation situations pretty well. Often times these things fall apart as soon as you run into a mildly complex situation such as dependent rule processing etc. Using this for WPF and MVVM as it turns out is pretty simple. In this post I will show you a simple example of how to integrate FluentValidation.Net into your View Models, using the IDataErrorInfo interface and the databinding support provided by WPF.
Here is what I will cover in the post.
If you do not have Unity and the FluentValidation dll’s, please learn how to use NuGet and go get it.
Very basic XAML here the intent is only to get the moving parts setup, not to win a beauty contest. Two things to notice here.
<ribbon:RibbonWindow x:Class="MoreFluent.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary" Title="MainWindow" x:Name="RibbonWindow" Width="640" Height="480"> <Grid x:Name="LayoutRoot"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <ribbon:Ribbon x:Name="Ribbon"> <ribbon:Ribbon.ApplicationMenu> <ribbon:RibbonApplicationMenu SmallImageSource="Images\SmallIcon.png"> <ribbon:RibbonApplicationMenuItem Header="Hello _Ribbon" x:Name="MenuItem1" ImageSource="Images\LargeIcon.png" /> </ribbon:RibbonApplicationMenu> </ribbon:Ribbon.ApplicationMenu> <ribbon:RibbonTab x:Name="HomeTab" Header="Home"> <ribbon:RibbonGroup x:Name="Group1" Header="Group1"> <ribbon:RibbonButton x:Name="Button1" LargeImageSource="Images\LargeIcon.png" Label="Button1" /> <ribbon:RibbonButton x:Name="Button2" SmallImageSource="Images\SmallIcon.png" Label="Button2" /> <ribbon:RibbonButton x:Name="Button3" SmallImageSource="Images\SmallIcon.png" Label="Button3" /> <ribbon:RibbonButton x:Name="Button4" SmallImageSource="Images\SmallIcon.png" Label="Button4" /> </ribbon:RibbonGroup> </ribbon:RibbonTab> </ribbon:Ribbon> <Grid Grid.Row="1" Margin="7,7,7,7"> <StackPanel Orientation="Horizontal" Height="24" Width="250"> <Label>Name</Label> <TextBox Width="150" Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"></TextBox> </StackPanel> </Grid> </Grid> </ribbon:RibbonWindow>
I suppose I should give you a screen shot. Not so pretty but good enough to get the point across!
And of course the CodeBehind. However minimal this is there are a few important things here to point out.
using Microsoft.Practices.Unity; using Microsoft.Windows.Controls.Ribbon; namespace Validation { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : RibbonWindow { /// <summary> /// Gets or sets the view model. /// </summary> /// <value>The view model.</value> [Dependency] public MainWindowViewModel ViewModel { get { return (MainWindowViewModel)DataContext; } set { DataContext = value; } } /// <summary> /// Initializes a new instance of the <see cref="MainWindow"/> class. /// </summary> public MainWindow() { InitializeComponent(); } } }
The MainWindowViewModel exposes a single property and the implementation of the IDataErrorInfo interface. Notice again we are relying on Unity to inject the Validator. In real life the the IDataErrorInfo implementation would reside in some sort of base ViewModel class. For example purposes I will not be doing that here.
Notice the IDataErrorInfo indexer, this forwards the call to the Validator asking it to run any rules associated to the supplied property name. If any rules are broken the error messages are returned in a single string with line breaks between each error message. Additionally the Error property asks the Validator to Validate all of the rules on a given object and return the enumerated results, again including line breaks.
using System; using System.ComponentModel; using System.Linq; using FluentValidation; using Microsoft.Practices.Unity; namespace MoreFluent { public class MainWindowViewModel : IDataErrorInfo { #region Dependencies /// <summary> /// Gets or sets the validator. /// </summary> /// <value>The validator.</value> [Dependency] public AbstractValidator<MainWindowViewModel> Validator { get; set; } #endregion #region Properties /// <summary> /// Gets or sets the name. /// </summary> /// <value>The name.</value> public string Name { get; set; } #endregion #region IDataErrorInfo Members /// <summary> /// Gets an error message indicating what is wrong with this object. /// </summary> /// <value></value> /// <returns>An error message indicating what is wrong with this object. The default is an empty string ("").</returns> string IDataErrorInfo.Error { get { return Validator != null ? string.Join(Environment.NewLine, Validator.Validate(this).Errors.Select(x => x.ErrorMessage).ToArray()) : string.Empty; } } /// <summary> /// Gets the <see cref="System.String"/> with the specified property name. /// </summary> /// <value></value> string IDataErrorInfo.this[string propertyName] { get { if (Validator != null) { var results = Validator.Validate(this, propertyName); if (results != null && results.Errors.Count() > 0) { var errors = string.Join(Environment.NewLine, results.Errors.Select(x => x.ErrorMessage).ToArray()); return errors; } } return string.Empty; } } #endregion } }
Of course this would be incomplete without the Validator so here it is! Just one simple rule.
namespace FluentValidation { /// <summary> /// Validator for the MainWindowViewModel /// </summary> public class MainWindowViewModelValidator : AbstractValidator<MainWindowViewModel> { #region Constructor /// <summary> /// Initializes a new instance of the <see cref="MainWindowViewModelValidator"/> class. /// </summary> public MainWindowViewModelValidator() { RuleFor(x => x.Name).NotEmpty().WithMessage("Name is Required"); } #endregion } }
Setting up Unity is simple. Two things need to be done.
<Application x:Class="MoreFluent.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Application.Resources> <!-- Resources scoped at the Application level should be defined here. --> </Application.Resources> </Application>
using System.Windows; using FluentValidation; using Microsoft.Practices.Unity; namespace MoreFluent { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); IUnityContainer container = new UnityContainer(); container.RegisterType<AbstractValidator<MainWindowViewModel>, MainWindowViewModelValidator>(); var mainWindow = container.Resolve<MainWindow>(); mainWindow.Show(); } } }
Enjoy!
Dates always seem to give me a headache when working with business apps. Trying to come up with framework level support for handling them is not always easy. In this post I will outline an approach to dealing with dates that we are using with some success in my current project. Much praise to Matt Lindstrom for the actual implementation of what I am going to outline here.
ORM Mapping
In most databases columns defined as date types can be built to allow nulls. This makes sense when you consider the implications for reporting etc. In .Net the native DateTime object is a value type, thus it cannot represent null. To correct this inconsistency we leverage Nullable<DateTime> for all date properties. And to prevent all the nasty ‘HasValue’ checking in our ORM methods we use an extension method on Nullable<DateTime> as follows.
/// <summary> /// Prepares for database. /// </summary> /// <param name="dateTime">The date time.</param> /// <param name="includeTimeStamp">if set to <c>true</c> [include time stamp].</param> /// <returns></returns> public static object PrepareForDatabase(this Nullable<DateTime> dateTime) { if (dateTime.HasValue) { return dateTime.Value; } return DBNull.Value; }
This method could be used the following way.
/// <summary> /// Method used to build command /// </summary> /// <param name="database">Database to run command against</param> /// <returns>Fully loaded command object ready to execute</returns> public override DbCommand GetCommand(Database database) { DbCommand command = database.GetStoredProcCommand("MyInsertCommand"); database.AddInParameter(command, "DATE_in", DbType.DateTime, SomeNullableDate.PrepareForDatabase()); return command; }
Of course this code only covers the mapping to the data store some additional work is needed when saturating objects with data. Again to support this we added an extension method on the CSLA SafeDataReader. Here we also account for the MinDate assuming that it is the same as a null date.
/// <summary> /// Gets the nullable date time. /// </summary> /// <param name="data">The data.</param> /// <param name="i">The i.</param> /// <returns></returns> public static DateTime? GetNullableDateTime(this SafeDataReader data, int i) { if (data.GetDateTime(i).Equals(DateTime.MinValue)) { return null; } return data.GetDateTime(i); }
And in practice
/// <summary> /// Method used for ORM mapping of CompRehabCase /// </summary> /// <param name="data">SafeDataReader</param> private void Populate(SafeDataReader data) { LoadProperty<Nullable<DateTime>>(SomeNullableDateTime, data.GetNullableDateTime(data.GetOrdinal("SOME_DATE"))); }
And that all folks.
Nullable<DateTime>
Often times during the development of enterprise software requirements arise stating that specific operations need to be handled both synchronously and asynchronously. A perfect example of this is printing. Perhaps a user wishes to print a document and wait for confirmation of a successful print operation before moving on to the next step of their business process. Or perhaps the user wants to request a print operation for multiple documents in a fire and forget fashion. In one case we should provide some sort of user interface cue as to the status of the print operation and in the other we just fire and forget, while hoping everything works out.
So we have a WPF window with a Print Button we also have a label to indicate the status of the running print job.
<Window x:Class="WpfApplication2.Print" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Print" Height="300" Width="300"> <Grid> <StackPanel> <Button Command="{Binding Path=PrintCommand}">Print</Button> <Label Content="{Binding Path=PrintStatus}"/> </StackPanel> </Grid> </Window>
using System.ComponentModel; using System.Threading; using System.Windows; namespace WpfApplication2 { /// <summary> /// Interaction logic for Print.xaml /// </summary> public partial class Print : Window, INotifyPropertyChanged { #region Private Data Members private string mPrintStatus; #endregion #region Constructor /// <summary> /// Initializes a new instance of the <see cref="Print"/> class. /// </summary> public Print() { InitializeComponent(); DataContext = this; PrintCommand = new RelayCommand(PrintExecuted); PrintStatus = "Ready"; } #endregion #region Private Methods /// <summary> /// Prints the specified parameter. /// </summary> /// <param name="parameter">The parameter.</param> private void PrintExecuted(object parameter) { PrintStatus = "Print Executed"; //Long Running Print Operatoin Thread.Sleep(1000); PrintStatus = "Print Completed"; } #endregion #region Public Properties /// <summary> /// Gets or sets the print status. /// </summary> /// <value>The print status.</value> public string PrintStatus { get { return mPrintStatus; } private set { mPrintStatus = value; var handler = PropertyChanged; if (handler != null) { PropertyChanged(this, new PropertyChangedEventArgs("PrintStatus")); } } } /// <summary> /// Gets or sets the print command. /// </summary> /// <value>The print command.</value> public RelayCommand PrintCommand { get; private set; } #endregion #region INotifyPropertyChanged Members /// <summary> /// Occurs when a property value changes. /// </summary> public event PropertyChangedEventHandler PropertyChanged; #endregion } }
Looking at the code here you can see that the intended behavior is as follows.
This sequence of events does actually happen, the problem however is that it all happens within the execution scope of the PrintExecuted method. Since this method is blocking until completed the user never sees the nice status updates we provide.
Before Click
When the window is loaded the status is set to ‘Ready’ as seen in the image on the left. Once the print button is clicked we want to change the status to ‘Print Executed’ and finally when the PrintCommand is complete to ‘Print Complete’. However since the updates to the status all happen while the UI thread is blocking, the status of ‘Print Executed’ never makes it to the user. Instead the status will transition from ‘Ready’ directly to ‘Print Completed’ upon command completion. This presents a pretty serious issue if you need to give the user meaningful feedback about what is going on. On interesting way to get around this is to use DoEvents.
If you came to the wonderful world of WPF DoEvents was something new to you. In fact when I first presented this problem to a colleague with a strong Win Forms background he was quick to mention this. So what is it?
To make a long story short DoEvents allows you to interrupt current event processing in order to process waiting events in the message pumps message queue. The good/bad news depending on your view of such things, is that if you need to replicated DoEvents in WPF you can. Because WPF and WinForms both leverage the User32 message pump. the solution ends up to be very simple Lets take a look and what our PrintExecuted method might look like.
#region Private Methods /// <summary> /// Prints the specified parameter. /// </summary> /// <param name="parameter">The parameter.</param> private void PrintExecuted(object parameter) { PrintStatus = "Print Executed"; Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })); Thread.Sleep(1000); PrintStatus = "Print Completed"; } #endregion
This approach give us the desired behavior of all of the status updates being presented to the user. Why this may not be a great illustration of proper use of an admitted hack. It is always good to have another tool in your toolbox.
Enjoy!