ASP.NET MVC3 And Other Microsoft Web Development Goodies

Last week, Microsoft unleashed a whole slew of new web development products for us to get to get excited about here at Affirma.  In fact, I think I’ll still Vishal Joshi’s sentiment of feeling like we are in a “Web Development Candy Store”!  The timing couldn’t have been more perfect as well, as we are just kicking up a new web development project that I have determined to use ASP.NET MVC3 along with some of these other new tools.  So I thought I’d take a moment to post some of my favorite bits that I have experienced so far.

Razor View Engine

Maybe it’s me, but when I was previously working on ASP.NET MVC projects, I always felt like I had some code-smell funk emanating from me when I’d look at those view pages filled with server code syntax that I’ve been seeing from WebForms and even ASP development.  MVC development is quick and lean to me and I always wanted a syntax that matched.  Enter Razor!

Old Way  Sad smile

<div class="contacts">
<% foreach (var c in contacts) { %>
<b><%= c.Name %></b> - (<%= c.PhoneNumber %>)<br>
<% } %>
</div>

New Way Smile

<div class="contacts">
@foreach (var c in contacts) {
<b>@c.Name</b> - (@c.PhoneNumber)<br>
}
</div>

And it has all the in-line, multi-line, nesting, and HTML helper support that I would expect.  Just keeps things clean and development fluid.

Razor Layouts/Sections

Like master pages, only better!  Okay, so that may be debatable, but being able to define the body or sections for widgets and other partials in a clean and simple manner just makes more sense to me.

@if (IsSectionDefined("widget"))
{
    <div class="widget">
    @RenderSection("widget")
    </div>
}

@section widget {
<h3>Featured Articles</h3>
@Html.Action("Featured", "Articles")
}

SQL Compact 4

Okay, so we probably aren’t going to be deploying any of our website projects using SQL CE 4.  However, being an environment we many of us are on the go and working from different locations, it servers as a nice, lightweight database that our developers can use to whip up some code and features without having to make sure there is a SQL Server box to connect and query against.  Also, I think there are some cool rapid prototyping opportunities here to help us engage prospective clients.
NuGet

Just started using this, but I’m already a fan.  What is NuGet?  Simply put, it’s a quick and easy to way to integrate all those tools and packages you use to develop right into Visual Studio.  Starting up my new MVC3 project, I knew I wanted NUnit, RhinoMocks, Fluent Route testing, as well as some other tools that I knew were scattered around on my hard drive but wasn’t sure if they were up to date.  No worries!  Just open up the console and type “Install-Package MvcContrib.Mvc3.TestHelper-ci” and boom!  My test project is almost set up!  I foresee a lot of value with this tool moving forward, so I’m looking forward into how it develops.

MvcScaffolding

Speaking of NuGet, this is probably the coolest library I’ve downloaded so far from NuGet.  It integrates right into the console and allows me to quickly code-gen, or “scaffold”, some of the basic MVC structures I’ll need for my project.  I created my business object, and then via one line I was able to generate an Entity Framework Code-First context, Repository, Controller, and all the views for CRUD operations.  Now, I didn’t need all the CRUD operations, but so what!  It’s easy to go in and delete or tweak what I didn’t need.  The tool is great for stubbing out the very basic bones of your project that you can then go in and build on top of.  Plus, it supports T4 templates so who knows what other cool scaffolds will be created by the open source community!

I’ll continue to post other nuggets of goodness I come across while working on this project, but for now there is definitely an abundance of web development candy for me to geek out over the next few weeks.  Just ask some of the folks around the office, I’ve been a jabbering fool on a sugar-high all week!

Comparable WeakReferences in C#

C# provides us with a WeakReference object.  This object behaves like a normal reference, except that it does not prevent garbage collection of the target instance it refers to.  So if every other strong reference to an instance goes away or is nulled out, the .NET garbage collector will collect that instance, without regard to the weak references.  WeakReferences also provide an IsAlive property so you can check if the target still exists.

The WeakReference class has a weakness in certain situations that I’d like to address.  Let me start with an example.

Suppose you have two weak references and you want to know if they point to the same instance.  Something like this (very naive) example:

object instance1 = new object();

WeakReference ref1 = new WeakReference(instance1);
WeakReference ref2 = new WeakReference(instance1);

if (ref1 == ref2)
{
    // Do something
}

This will actually fail every time.  It’s comparing the references to the WeakReferences.  Because ref1 is a reference to a WeakReference instance, as is ref2.  What we really want is to compare the targets.  (Usually.)

So here I present the EquatableWeakReference class.  It behaves just like a WeakReference, but if you compare two of them, it compares the targets.

public class EquatableWeakReference
    {
        #region Private Members

        private int _targetHashCode;
        private WeakReference _weakReferenceToTarget;

        private void setTarget(object target)
        {
            _targetHashCode = target.GetHashCode();
            _weakReferenceToTarget = new WeakReference(target);
        }

        #endregion

        #region Public Interface

        public EquatableWeakReference(object target)
        {
            setTarget(target);
        }

        public object Target
        {
            get { return _weakReferenceToTarget.Target; }
            set
            {
                setTarget(value);
            }
        }

        public bool IsAlive
        {
            get
            {
                return _weakReferenceToTarget.IsAlive;
            }
        }

        public override int GetHashCode()
        {
            return _targetHashCode;
        }

        public override bool Equals(object obj)
        {
            return _targetHashCode == obj.GetHashCode();
        }

        #endregion
    }

As you can see, it has a similar constructor, and the same properties as the WeakReference.  It wraps the WeakReference, rather than inheriting from it, because we originally wrote this for use in Silverlight and you can’t inherit from WeakReference in Silverlight.

When you set the target, it records the target’s HashCode.  This is a unique* identifier of that object instance.  It uses those HashCodes to do comparisons.  It also overrides GetHashCode to return the target’s HashCode, rather than the EquatableWeakReference’s HashCode.  This also provides the advantage that if you use an EquatableWeakReference as a key in a Dictionary, it will be treated as the same key as a real reference to that object, because Dictionaries use the HashCode to index values.

(Which brings us to the whole reason for creating this.  We needed to make a WeakDictionary.  A Dictionary that would allow values to be garbage collected if the key instance was no longer alive.  This was a single-point fix to a widespread memory leak in an open-source library we were working with.  Oh, memory leaks… How you amuse me…)

 

* – It’s not really 100% unique, but it was good enough for our purposes.

MVVM Enabling Database Driven Silverlight Applications

One of the more exciting projects we are working on here at Affirma is a line-of-business solution for a client that includes talking to a SQL Server backend.  This was a great opportunity to put our own MVVM framework to the test in developing a data-driven Silverlight client that would increase productivity and visibility for our customer.

There are a number of different topics from our lessons learned that could be covered in our blog, and I will definitely cover as many as possible in the future, but for now I just wanted to highlight how we were able to put together a group of technologies in a very quick timeframe to provide great value to our customers.

If you are unfamiliar with MVVM, don’t fret!  You can read this quick overview from Joel Wetzel on the topic to get a quick understanding, but for now just think of it as a group of patterns and practices wrapped into a framework that allows us to build testable and reusable components with great flexibility.  It’s also a topic we will cover in blog posts in the future.

For this project, we used the following technologies:

  • Microsoft SQL Server 2008
  • Silverlight 4 (including the Toolkit)
  • Silverlight Unit Testing Framework
  • Windows Communication Foundation
  • DevExpress Silverlight Controls
  • .NET 4.0, ASP.NET 3.5/4.0, RhinoMocks, nUnit, MSTest, and others

The requirement from our customer was to provide an interface for their managers to modify and insert business data in monthly batches that would then report up to business operations for accounting and other purposes.  The managers were also familiar with WPF clients and so Silverlight seemed like a great choice for their intranet needs.  To understand how all these pieces fit together, here is a pretty little architecture diagram.

Now for the tricky part.  Silverlight runs on the client UI thread and cannot talk directly to SQL or other server code that requires a network connection.  So how is this accomplished?  With a little asynchronous, anonymous delegate gravy!!

using System;
using System.Collections.Generic;
using Affirma.Silverlight.Services;

namespace SilverlightLOB.DomainServices
{
    public interface IDomainService : IClientService
    {
        void Add(BusinessObject businessObject, Action<IResult<bool>> action);
        void GetItemsFor(Store store, Action<IResult<IEnumerable<BusinessObject>>> action);
    }

    public class DomainService  : IDomainService
    {
        public void Add(BusinessObject businessObject, Action<IResult<bool>> action)
        {
			// our web service proxy
            var client = new DataServiceClient();

            client.AddCompleted +=
                (obj, args) =>
                {
                    if (args.Error != null)
                        Logging.Log.Debug("Error in Add - " + args.Error.Message);

                    action.Invoke(new SimpleServiceResult { Error = args.Error });
                };

            client.AddAsync(businessObject);
        }

        public void GetItemsFor(Store store, Action<IResult<IEnumerable<BusinessObject>>> action)
        {
            var client = new DataServiceClient();

            client.GetItemsForCompleted +=
                (obj, args) =>
                {
                    if (args.Error != null)
                        Logging.Log.Debug("Error in GetItemsFor - " + args.Error.Message);

                    var result = new EnumerableServiceResult<BusinessObject> {Error = args.Error};
                    if (result.Success)
                        result.Value = args.Result;

                    action.Invoke(result);
                };

            client.GetItemsForAsync(store);
        }
    }
}

Easy!  This domain service lives on the client UI thread and will execute asynchronous requests to our WCF service, and invoke the result back onto our UI thread thanks to the provided callback.  This means the Silverlight client UI can continue to execute requests and other user interactions while the service requests process and returns a value.  From our view model, we can easily wire up to this domain service and execute the appropriate asynchronous method.

public ICommand AddCommand
{
	return ConstructCommand(() => AddCommand, AddHandler);
}

void AddHandler()
{
	_service.Add(ObjectToInsert,
		result => {
			if (result.Success) MessageBox.Show("Success!");
		};
}

Undo/Redo and Encapsulated Data Changes in Silverlight

We’re currently working on a Silverlight application that needed a robust undo/redo system.  Every change a user could make to data needed to be able to be undone.  At Affirma, we have a set of tools we’ve built for Silverlight – using an MVVM and Service-Oriented pattern – but this was not a tool already in it!  No matter, the great thing about a tool like an undo/redo system is that it must be a general tool, and so it could be added to our toolkit for use on many projects.

The way we chose to go about making this system was to abstract out the idea of a “Change”.  In the abstract, a change would be an encapsulated something (also known as a class, but the dramatic form is fun) that knew how to alter data both forwards and backwards.  Okay, that’s pretty abstract, so how about an example.  Let’s say we have a DeleteChange that can remove a piece of data from a repository.  This DeleteChange would need to know what piece of data it had to delete, it would need a way to delete that data, it would need to keep track of that data so the change could be undone, and it would need a way to add the data back for an undo.

Okay, some code:

namespace Affirma.Silverlight.Changes
{
    public abstract class Change
    {}

    /// <summary>
    /// A change does and undoes work on a target.
    /// </summary>
    public abstract class Change<TargetType> : Change
        where TargetType : class
    {
        /// <summary>
        /// An implementation should override this method and do work on the target here.
        /// </summary>
        public abstract void Do(TargetType target);

        /// <summary>
        /// An implementation should override this method and undo work on the target here.
        /// </summary>
        public abstract void Undo(TargetType target);

        /// <summary>
        /// An implementation should override this method and notify any listeners of the change here.
        /// </summary>
        public abstract void Notify(TargetType target);

        /// <summary>
        /// An implementation should override this method to finalize doing and undoing the action here.
        /// </summary>
        /// <param name="target"></param>
        public abstract void Finalize(TargetType target);
    }
}

A few notes:

1 – You would make a child class for each type of change you might want to make to your data.

2 – The changes are strongly typed (through generics) to the data object they will act upon.

3 – You implement methods for doing the change and undoing it.

4 – We added a Notify method.  In practice, often other systems would need to know about the change, so this is where you could notify them.

5 – We often found that we needed to “preview” a change, but not finalize it.  An example would be dragging an element around the screen.  We might need to “test the waters” of the change as we drag the element around, but we don’t want to finalize the change until we drop the element.  That’s why we have a finalize method.

6 – You’re probably getting the feeling about now that this system requires some discipline.  It does.  You MUST NOT alter data anywhere but inside a change.  However, we found that in practice, using that discipline up front saved us a lot of time down the road.  We always knew where to look to find where the data changed.  Data changes weren’t hiding in corners of the system.  And there was fantastic encapsulation.  Clients shouldn’t know what it takes to change the data.  They usually shouldn’t even know about all the data!  They just know they want a change, and these classes encapsulate it.

Okay, so the next step.  We wrote a service (internal to the Silverlight application) to manage these changes.  Here’s the interface:

namespace Affirma.Silverlight.Services
{
    /// <summary>
    /// An IChangeManagerService is used to manage data changes in systems where undo/redo
    /// functionality is desired. It is a generic interface, and the generic type is the type of
    /// the target that all the changes will act upon.  Generally, the target will be the root
    /// of a model graph.  The changes act upon this target to do their work, undo it, and redo it.
    /// </summary>
    /// <typeparam name="TargetType">The type of the target that all the changes will act upon.  Generally, the target will be the root of a model graph.</typeparam>
    public interface IChangeManagerService<TargetType> : IClientService
        where TargetType : class
    {
        /// <summary>
        /// Registers the target for all the changes.  This must be done before changes can be done.
        /// </summary>
        /// <param name="target"></param>
        void RegisterTarget(TargetType target);

        /// <summary>
        /// Performs a change, but does not commit it yet.
        /// </summary>
        void PreviewChange(Change<TargetType> newChange);

        /// <summary>
        /// Commits the currently previewed change.  It will be added to the undo stack.
        /// </summary>
        void CommitChange();

        /// <summary>
        /// Previews and commits a change in one step
        /// </summary>
        void CommitChange(Change<TargetType> newChange);

        /// <summary>
        /// Undoes the previewed change.
        /// </summary>
        void CancelChange();

        /// <summary>
        /// Undoes the most recent change.
        /// </summary>
        void Undo();

        /// <summary>
        /// Redoes the most recently undone change.
        /// </summary>
        void Redo();
    }
}

Notes on this:

1 – Currently, this service only supports one target.  It could be expanded to have multiple targets and you would tell it what target the change should act upon.

2 – The interface is a higher abstraction than that of the changes.  For example, preview.  Previewing a change calls Do and Notify, but not Finalize.  If you preview a second time before finalizing, it calls, Undo on the old change, and then Do and Notify on the new one.  Finalize gets called when you commit the change.  This is to support the previously-mentioned drag-and-drop scenario.

3 – The ChangeManagerService keeps track of changes that have been done and undone in two stacks.  It support infinite undo, but we could put a limit in.

The end result of all this work:  Encapsulated Object-Oriented changes.  Do/Undo/Redo capability.  And the ChangeManagerService is ready and waiting for more projects!

Next time I’ll talk about an extra we just added to the ChangeManagerService.  Object-Oriented business rules. Awesome.

Tool for Developing HLSL Pixel Shaders for WPF and Silverlight

Update:  Follow-up with source and live demo posted here!

The other day, I found a truly great tool.  It’s called Shazzam and its for use in developing HLSL pixel shaders for WPF and Silverlight.  It has an editor for writing your HLSL, automatically compiles your shader, lets you test it against an image or video, including playing with the inputs.  And finally, it automatically writes a C# or VB wrapper for your shader to let you use it as an effect in your WPF or Silverlight project.  This is just a great tool.  Make sure to support the authors.

Shazzam

A few examples of pixel shader effects we made with the help of Shazzam:

An animated underwater wavy/blurry filter:

Underwater Pixel Shader

A shader for doing telescopic blur:

Telescopic Blur

Silverlight and MVVM

All of Affirma Consulting’s Silverlight projects use the MVVM (Model-View-ViewModel) pattern.  This design pattern is modular, testable, and takes advantage of Silverlight’s powerful data-binding capabilities.

A selection of resources on MVVM and Silverlight:

5 Minute Overview of MVVM

MVVM Light Toolkit

Wikipedia Entry

You can find many, many more with a quick Google search and you’ll quickly learn that arrayed around the central MVVM pattern, people tend to use things like ServiceLocator patterns, variations on Observer or Signals And Slots to perform messaging between ViewModels, and that really no one completely agrees on what MVVM is.  That’s one thing you quickly discover.  There 8 dozen existing MVVM frameworks out there.  They each wire up the references in a different way.  And they each contain a different sampling of satellite features.

For example, what is a ViewModel?  Is it a view into the Model?  Maybe.  It certainly wraps the model data in a form that is useful for the view.  But more than that, it’s a model of the view.  The ViewModel maintains state for the View.  Anything in the View that can change should be bound to a property on the ViewModel.  But now the ViewModel is performing two jobs, which is a violation of singularity of purpose.  So we could split it in two and have a model wrapper and a view state machine.  There’s a reason no one does this.  It’s just too much make-work for the payoff.  When done well, our ViewModels tend to be pretty simple anyway.  Why create roadblocks between the view state and the model state?

This is just the first of many postings we’ll be making on MVVM.  Check back frequently for discussions of the intricacies.

%d bloggers like this: