Smart Clients

WPF layer for Composite UI Application Block (CAB)

We've been doing a ton of CAB work over the last year and have been having a lot of success.  The CAB framework has provided us with a great foundation for building a modular software application which can be customized on a per client basis.  Sam and others on the team have made a couple pushes to try and get WPF incorporated into our product.  Due to the fact that CAB doesn't come with built in "support" for CAB, as well as some other internal factors we haven't yet made the plunge.  I'm hopeful that the Patterns & Practices team will start up another development cycle with the goal of porting CAB to a WPF.  However, if that doesn't happen perhaps the WPF layer for CAB project on CodePlex will provide us with what we need?

 

Technorati tags: , ,

Increase the performance of CAB and ObjectBuilder

We've recently been discussing ways that we might be able to reduce the start up time for our application.  One of the approaches is to implement some client side caching of lookup data which will reduce the amount of times we need to go across the wire during startup.  A second area that we've been investigating is how we might be able to reduce the overhead that comes with the reflective nature of CAB/ObjectBuilder.  During startup ObjectBuilder reflects upon the modules that make up a CAB application so that it can perform all its magical wonder such as wiring up EventSubscription's, EventPublication's, ServiceDependency's, and etc. 

Although we haven't done any testing to see if they help, I'm very interesting to checkout the CabGen and ObGen tools that are available in the latest drop of the Mobile Client Software Factory.  You can read a little more about the reasoning behind the tools in Eugenio's "Notes on (extreme) Performance requirements for CAB" post.  I'll report back with findings...

 

Technorati tags: , , , ,

Occasionally Connected Clients and the ADO.NET Sync Framework

We've recently been thinking about data synchronization options for our Smart Client application.  While we don't see allowing a truly disconnected experience we would like to reduce the amount of data that we need to send between our application servers and our smart client.  Since we're going to have deployment scenarios where our app server is across a big ocean from where our client sits we need to start thinking about how we can reduce the amount of data going across the wire.

This weekend I watched Steve Lasker's screencast on the upcoming sync framework that may be a part of Orcas.  With all the talk surrounding LINQ, LINQ to Entities, and the ADO.NET Entity Framework I somehow missed any mention of the Sync component that is being worked on.  In his demo Steve shows a simple demonstration of the various scenarios that the Sync framework supports and briefly talks about how SQL Server Compact Edition fits into the equation.  I'm concerned about the tight coupling the the sync framework appears to have on DataSets as our architecture doesn't exactly include anything DataSet related. Regardless, it seems like there is some interesting developments happening in the Occasionally Connected space now that SQL Server Compact Edition is getting closer to release.

Technorati tags: , , ,

CAB Best Practices

This past week I attended the Smart Client Baseline Architecture Toolkit (SC-BAT) workshop out in Redmond.  Overall it was a very beneficial week.  I learned a lot about CAB best practices and also got to meet some members of the core patterns and practices team as well as some other Microsoft employees whom I had “heard” of.

It was also my first trip out to Redmond so it was fun to see what Microsoft was like…it’s HUGE.  Anyway I thought I’d get going with some posts on what I learned and how I’ll apply what I learned.  This first post is a simple list of the best practices that I came away with.  Hopefully future posts will be more beneficial for those who don’t know much about CAB.

  • There should be a 1–1 relationship between a view and it’s presenter.  Presenters are seen as an implementation detail of a view so nothing outside of the view should know about the presenters existence.  [CreateNew] is your friend when it comes to creating a presenter for your view.
  • Since views know about their presenter (and vice versa) any work that needs to be done by the view should be directly delegated to it’s presenter.  The presenter should handle all work that the view needs done.  The view should just display data and be extremely “light”.  The event broker should NOT be use to communicate between a view and it’s presenter.

private void button_Click(object sender, EventArgs e) {
   _presenter.DoMyButtonClickStuff();
}

  • If views need to “communicate” between each other they should use EventPublication/EventSubscription.
  • WorkItem’s sole purpose in life is to be a container.  Rather then being anything “Use Case” related treat WorkItem as what it is, a container.
  • The logic necessary for adding views, services, and etc. to a  WorkItem should live inside a Controller class.  Since the controller needs to know about it’s WorkItem the ControlledWorkItem class should become one of your good friends.
  • Controllers are used to get things wired up and running, and for adding everything necessary to the container (aka WorkItem).
  • If possible your views should implement the ISmartPartProvider interface.  This allows the view to determine how it is displayed within your workspace(s).
  • Views and Presenters should implement IDisposable so they can be cleaned up properly.
  • The Guidance Automation Toolkit is your friend.  Learn it, live it, love it!

Writing my First Module for CAB

Now that I have my first CAB application I want to figure out how to write a “Module” within CAB. 

“Modules are distinct deployment units of a CAB Application. You can separate areas of your application into different modules to be able to deploy them to different users or applications.”

Step one is to create a separate project for a module, which I’ll call MySampleModule.  Next we’ll want to add a class to initialize our module which we’ll name MySampleModuleInit.  Our MySampleModuleInit class will inherit from the ModuleInit base class provided by CAB.  To keep it simple we’ll show a message box with a fancy “Hello World” message.  When you create a new Module you likely have some initialization logic that you want to run which is what the whole ModuleInit class is all about.  You might also want to initialize some of the services used by your module within the initialization stage.

public class MySampleModuleInit : ModuleInit {
   public override void Load() {
      base.Load();
      MessageBox.Show("Hello World");
   }
}

After we’ve created out MySampleModuleInit class we want to make it so our primary shell application knows about our new module.  To do this we define the module within a ProfileCatalog.xml file within our shell application.  In addition to adding the module definition to the ProfileCatalog.xml files we also need to add a reference to our module project so that when the shell loads it can find your module.

<?xml version="1.0" encoding="utf-8" ?>
<
SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile"
>
    <
Modules
>
         <
ModuleInfo AssemblyFile="MySampleModule.dll"
/>
    </
Modules
>
</
SolutionProfile>

Once the  main application and module are compiled the application can be run.  When the shell application starts it will pick up on the ProfileCatalog.xml file and use the information within the file to determine what modules it needs to load.  Each module will be loaded and will have it’s initialization logic executed.  While a module that displays a “Hello World” message is amazingly useful I think the next step is to move onto creating a Module that has a real UI.  In addition we should start exploring what WorkItems, Controllers, and SmartParts are all about.

My First CAB Application

Over the last several months I’ve been keeping an eye on the progress of the Composite UI Application Block.  Earlier this month Peter, Brad, and the rest of the PAG group released the November release of CAB.

Tonight I started looking over some of the sample applications and walkthroughs provided as part of the CAB release.  To start learning about CAB I’ve decided to start writing a simple application using it.  The first step in the learning process is to get up to speed on how creating the most basic application is different in CAB then in a “normal” WinForms application.

When we create a normal WinForms application we get a program.cs file that runs our main form.  To get a simple form to show up in a CAB application we need to create three items.  Just like in a typical WinForms app we need a default form, but unlike a normal WinForms app we also need a default work item, as well as a “shell” for our application. 

public partial class ShellForm : Form  {
   public ShellForm() {
      InitializeComponent();
   }
}

public class ShellWorkItem : WorkItem {}

public c

lass ShellApplication : FormShellApplication<ShellWorkItem, ShellForm> {
   [STAThread]
   static void Main() {
        new ShellApplication().Run();
   }
}

Most of the wiring up of this sample CAB application happens in the definition of the ShellApplication.  As you can see I’m inheriting from the FormShellApplication base class and providing it the type of the default work item (ShellWorkItem) as well as the form to use as the “Shell” for the application.  Running the CAB application once the Form, WorkItem, and Shell are defined results in a beautiful blank form just like we get out of the box when we create a blank WinForms application. 

Smart Client Development

Jay Fields has a series of posts going which he’s using to document how he’s been doing smart client development.  He seems like the type of guy who might agree with me that the WinForms Designer is Evil.

Is Smart Client a Dumb Idea

Rob Howard has an interesting post entitled Is “Smart Client” a “Dumb Idea?” where he talks about why he thinks smart clients are in fact a dumb idea in most scenarios.

Do you agree?

The UI is important

As programmers we often dismiss the importance of a good UI.  If we make our services, components and objects as slick as we’ve planned we won’t even need a UI. Who needs an application that’s usable when we have this great API?

If you haven’t already started thinking about the usability of your applications…start now.  As programmers we often lose sight of how our users will interact with the application we’re creating.  We often think that the most features possible is the answer. 

Listen to guys like Jan Mikosvsky, learn to love a nice UI!

Is ClickOnce too late?

One of my favorite features within .NET 2.0 is ClickOnce.  I’ve deployed two prototype applications using ClickOnce and overall I’m a big fan.  As a “web guy” learning about win forms I love the fact that I can continue to have an easy deployment in the Win Forms world.  Every time I load up an app and get the nice dialog asking me if I want to get the latest version everything feels right in the WinForms world.  No longer do I have to uninstall and reinstall applications, I just click on the application and it automatically updates itself if a new version is available.

Although ClickOnce is a great technology I wonder if it’s too late to the party.  The average corporate business user has been brainwashed to think that if it’s not a web app it’s not for them.  Over the past couple of years the industry has strongly advocated the web and slowly but surely most business applications have been converted to a web platform.  With the migration to the web IT departments have gained the benefit of having an “easy” deployment, and users have been granted access to their applications from anywhere in the world.  Ah….the power of the web.

With the added benefits of mobility and easy deployment also come some costs.  The web is a stateful beast.  Many a developer has spent endless hours trying to make their web app feel more like a windows app.  It turns out users want responsive applications along with that mobility and easy deployment.  In an attempt to provide users with a more responsive interface developers across the world have tried endless hacks.  Out of all these hacks has come AJAX.  The saviour of the web platform.  The technology that will bring the responsiveness of  a windows app to the browser.  Erm, I’m not sure I buy that.  While some applications will be able to leverage AJAX to provide users with a more responsive application, AJAX != Windows.  No matter how much AJAX you sprinkle on your web application you will not get the responsiveness you will get from a Windows App.  AJAX is cool, AJAX will help improve the usability of some applications, AJAX DOES NOT MEAN WE SHOULDN’T DEVELOP ANY MORE WINDOWS APPLICATIONS.

A very large number of business applications in the world today could see tremendous value in moving back to a Windows world.  That’s right I said it.  Move you applications from the web back to Windows.  Of course do so only if you can develop your application using .NET 2.0 and ClickOnce.    And only do so if it actually makes sense, don’t start moving your web based shopping cart to a Windows app.  Do consider moving your web based business applications back to Windows. 

I’m sure your thinking to yourself, “are you nuts?”. 

Do I really expect you to give up your mobility?
No. In fact I’ll give you even more mobility.  I’ll create a Smart client application that provides offline support.  This way you can “get shit done” (tm) even when you have no Internet or wifi connection.  Sure it won’t be 100% fully featured when your in disconnected “mode” but it will be a lot more featured then your “Server not found” page.

Do I really expect you to give up on your web application that you can access from any platform?
Yes.  The fact is many business applications out in the world today only support a single browser anyway (IE), so just pretend that when you click on the link to the application that it’s opening in IE.  I’ll even give you a toolbar that looks like IE if it will make you feel better.  With that said if you really do need to be able to access the application from a Mac, Windows, and Linux you may be better off with a web application.  I’ve found that most business application only support IE, if this is the case for you consider ditching the web for Windows!

The web is great for a lot of things, however, it is NOT great for everything.  If your building software using .NET consider fighting the urge to go with the flow and move everything to the web.  Give your users what they want.  Give them an application that is easy to deploy, provides them mobility, AND is responsive.  Give them a Windows app!

 

Keeping your UI Responsive

 Jessica Fosler has a nice post on Keeping your UI Responsive and the Dangers of Application.DoEvents.  Within it she discusses some options for removing calls to Application.DoEvents for updating the UI which may help improve the responsiveness of your app. 

Validation in WinForms is Lame!

WinForms validation is lame!

Coming from a web world where we have RequiredFieldValidator, CompareValidator, RegularExpressionValidator, and etc. to the WinForms world where we have, um, what do we have again?  Oh right…we have that validating event on our controls?!?! 

Why hasn’t form validation been something that was important to the WinForms team?  One of the nicest features (that I now realize that I took for granted) in ASP.NET was the “robust” validation capabilities available.  You’d think the WinForms team would have incorporated something similar into an initial release, ok, well maybe not an initial release but definitely a 2.0 release, or not.

For those peeps in the audience who started in the Web Forms world with nice validation controls checkout the Genghis project to get your fill.  The Genghis project brings the RequiredFieldValidator, CompareValidator, CustomValidator, RangeValidator, and RegularExpressionValidator to WinForms….woot!  If only it could have been baked into .NET 2.0.  Oh well I suppose I should just be happy such a project exists.

Where are all the cool built in WinForms controls?

As I’ve said time and time again I’m just moving into the WinForms world from a couple years in the web world.  One of the things I was interested in checking out in WinForms 2.0 was all the new controls.  Thus far I’ve been mostly disappointed.  I guess I was hoping to get some of the functionality that can be seen in the controls from Crownwood Software, Divelements, and others.  I was hoping for easy to create expandable and collapsible panels (ala Outlook 2003 & Eyefinder), dockable windows (SandDock), and just overall snazziness right out of the box.  Part of my problem is likely that I haven’t come across the properties that I’m looking for on the new controls to get the look that I want, or perhaps my expectations where just too high?

Looking for examples of "Slick" UI's

As if I haven’t already said it enough, I’m working on a Smart Client.  One of the things that I think is lacking in the current version of the application is the slickness of the UI.  I’m looking for ideas of how we might pretty it up a bit.  What’s your favorite application to work with?  What application have you used recently that you really liked the overall UI of? 

Two of my favorites:

  • BlogJet – simplicity!
  • FeedDemon – Can’t wait to get more goodness in v1.6
  • Outlook 2003

I’d actually prefer to hear about more “business-type” [1] applications, it just so happens I don’t work with too many of those

What are some of your favorites?

[1] CRM, ERP, etc…

Web Services, .NET Remoting, or Both?

As I’ve mentioned several times now I’m getting ramped up to begin work on a Smart Client application.  One of the discussions that we’re currently having within our team is what “transport” we should support.  Initial conversations focused on Web Services, however, some recent discussions have brought up some performance problems in the current app which caused us to start considering .NET Remoting.  With all the Indigo talk recently it’s tough for one to decide which way to go with current applications.  We’ve heard over and over that ASMX have a clear migration path for Indigo and we’ve heard over and over that .NET Remoting does not have the same clear migration path.  Those of us stuck in a world where we have to actually build applications today and not wait for Indigo are stuck in a difficult position.  Do we go with Web Services so that a future version of our product is better able to migrate towards Indigo or do we consider .NET Remoting so that upon our initial release our customers get the most performant application?

Web Service Advantages:

  • Better migration path towards Indigo
  • Multi-platform
  • Support for WS-* Specifications for dealing with security, addressing, reliable messaging, etc.
  • Team has worked a with WS
  • Provides an extensibility and integration point for customers

.NET Remoting Advantages

  • Performance

As of now the only advantage I have for .NET Remoting is performance.  When it comes down to it I think we’ll need to investigate where the existing performance problems are in our application to determine if it’s worth going with .NET Remoting.

We have also considered a third approach which would include support for both WS and .NET Remoting.  Under this design we would develop service agents that would know how to perform the necessary actions using either WS or .NET Remoting.  This would give us the best of both worlds, however, would force us into taking additional time to develop for both.  We’d also be increasing the ramp up time for developers working on the application as they’d have to learn about both WS and .NET Remoting.

What else haven’t I considered?  In what direction would you go?