Practical .NET

Adding Business Services in WPF with Prism and Unity

WPF with Prism and Unity allow you to create loosely-coupled applications that assemble themselves at run time. Here's how Prism and Unity allow you to dynamically integrate business logic into your application.

In an earlier column, I introduced WPF+Prism+Unity, which form Microsoft's recommended technology base for creating applications that assemble themselves at run-time. This technology set is all about creating loosely-coupled modules that you can update or replace without having to recompile every other part of the application. This strategy supports application development where an application is built by more than one person working in parallel, or where the application is expected to evolve over time, requiring components of it to be replaced.

In the WPF+Prism+Unity world (or Silverlight+Prism+Unity), an application begins with the Shell, which includes the user interface (a WPF window). That window displays one or more WPF User Controls. The rest of the code for the application itself is distributed over one or more Modules. In the previous article I created a Module consisting of a WPF User Control (a View) to be used in the Shell, and a class with all of the UI logic for the View (a ViewModel). What I didn't address was incorporating any non-UI business functionality: What, in "Prism-speak", is called a service. Fortunately, incorporating business logic isn't much different from incorporating UI logic.

Defining Service Modules
The first step is to define where the application will find its modules. You do that in the Shell (the start point for the application with the WPF form that forms the UI). There are a number of ways of doing that (and I'll eventually be looking at one other method, using a configuration file), but I'll stick with defining a folder in the same folder as the application's EXE. The next step is to create a second project to hold the service code and add a post-build event to the project's properties that copies the project's DLL to the folder (I described those steps in my previous column and won't drag you through them again).

The First Service Class
The new service Module project will have an initializer class (a class that Implements the IModule interface) that registers all the service classes that the module provides, using the Unity container that's passed to the initializer class's constructor. When you register a class in a container you specify the interface the class implements, the name of the relationship you're setting up between the interface and the class, and the lifetime manager you're using.

In my previous article I used the ContainerControlledLifetimeManager, which ensured that only one copy of the class would be created for the whole application. That made sense since I was loading a part of my user interface and knew that I'd only ever need one copy of the class. However, I could imagine that a service that supplies, for instance, Customer entities to the application might be created several times. So for this example, I'll use the TransientLifetimeManager, which ensures that an object is created each time it's created.

When I start building an application, I often start by creating a mock data access object that returns dummy data; this lets me test my UI interactions and workflow. So when creating my data access module, I would probably begin with a mock object that returns a fixed set of classes. This code, for instance, which I put in the Initialize method of my Module's initializer class, ties my ICustomerFactory interface to my MockCustomerFactory class using the name MockNWCustomerFactory and a TransientLifeTimeManager:

  Microsoft.Practices.Unity.TransientLifetimeManager tlm = 
   new Microsoft.Practices.Unity.TransientLifetimeManager();
cont.RegisterType(typeof(ICustomerFactory),
                typeof(MockCustomerFactory), "MockNWCustomerFactory", tlm);

To get this code to compile, I'll need to define the ICustomerFactory method and the MockCustomerFactory. For now, I'll just define a single method that returns all the Customers. Since I'm a big fan of data transfer objects, I define a DTO with just the Customer data that the application needs, an interface that includes a method that returns that DTO, and a mock factory object that generates some test data for me (as shown in Listing 1).

The MockCustomerFactory class itself will be one of the classes in my Module project. But that raises the question of where the files holding the DTO and the interface should be put. One choice is the Shell application, and having all the Modules add a reference to that project. A better choice is to create a separate "intfrastructure project" to hold your application's common resources. You can then add references to that project to your Shell and all of your Modules.

I'm now ready to test my application using the mock data returned by my mock class. That raises the question of where that object should be resolved -- a topic I'll address in my next column.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events