Introduction

The Visual Application Launcher (VAL) is a WinForms application that allows delivery of icons to users that can be double clicked to launch a file.

Background

VAL is useful for delivering bespoke applications, databases, and spreadsheets to users. In a corporate environment, it is very common to have data in formats
such as these that must be referred to by different departments.

E.g., Amy works in accounts, she needs access to the 'Budget Data' spreadsheet, an accounting Access database, an Intranet .NET web application, and an in-house
.NET WinForms application. John works in marketing, he needs access to the 'Budget Data' spreadsheet and the Intranet .NET web application. Dylan works in IT and needs
access to everything! How would you maintain all of this information? If the budget data spreadsheet is on a shared network drive, how will the user know where to go to launch the file?
This can be emailed around to the different users, but wouldn't it be easier if all of this could be centrally maintained and a list of 'shortcuts' delivered to the users
in a fancy user interface?

This is something that is often centrally managed for the main functionality of a user profile. Using the 'Amy' example, the domain administrator would grant permissions
on the account to deliver finance specific software that may be available to select from the user's 'Start' menu. However, this will rarely go to the granular level
of particular workbooks located on shares.

This is where VAL comes in - VAL has the concept of Groups, Users, and Files. Users and Files can be assigned to Groups and the system determines which Files the
User has access to by calculating their overall group membership.

Since the database schema for this application is simple, I decided to create an application that tests many of the current technologies and Design Patterns being
used in .NET today. While this works, it's massively over engineered for what it needs to achieve!

VAL is meant as a complete example of a number of .NET technologies and Design Patterns.

The solution contains examples of the following...

Using Entity Framework 4.2 (EF) to access data in a SQL Server database

Prerequisites

You'll need at least the following to use the application...

SQL Server 2005 or later

A machine (local or remote) with IIS

Visual Studio 2010

.NET 4.0

VAL also uses a number of Open Source libraries which are included as compiled assemblies and are located in the packages directory of the solution.
You can use the compiled assemblies, replace them with your own versions, or download source \ binaries from the associated web sites. The packages directory
was created by NuGet, so you can simply update the packages if you are using NuGet.

If you don't want to use the compiled assemblies included in this download, just drop the replacements into packages/lib and the solution will pick them up when you compile:

Getting Started

The first thing you'll need to do is create the database for the application, the virtual directory in IIS for the WCF services, and make a few changes to the app configuration.

I've included a ReadMe.txt that describes each setting and its impact on the system; please make sure you read through and follow the guide when trying
to get the application ready to run. Spending a few minutes going through the config is important.

Application Screens and Overview

The main user interface is a simple window that displays icons, this is the only screen that the majority of users of the system will ever see.

There are also administration screens that allow you to configure the different properties of VAL. Only members of the 'Administration Group' will have access to these screens.

Admin MDI Window

The admin window allows you to launch the various maintenance windows by clicking on the icons in the Toolbar. Each screen maintains a particular group of data.

User Maintenance

The user maintenance screen is where you create user profiles for use with VAL. Either manually type or use the 'Active Directory Browser' section to pick a user from your AD.

File Maintenance

File maintenance is where you define icons to be delivered to end users. Configure the location of the programs to launch, their types, the icon to display, and various other options.

Group Maintenance

The group maintenance screen is where you create groups and where you assign users and files to particular groups. This determines the set of overall
permissions (and therefore the icons displayed to the user).

That's a quick overview of the different screens available in VAL. Please see the associated help file included with the application which provides full details of each maintenance screen.

Using the Code

There's a lot of code to describe, so consider the following logical diagram first. This describes the data flow process from the highest level (the UI) across
application boundaries (WCF communication) to the lowest level (the SQL database).

This article will describe the process from the lowest level first.

The Database

There's very little to describe in the database, there are only tables, indexes, and relationships to consider in the schema. There are no views or procedures
used by the application source code. Cascade operations will occur on related tables during a Delete operation.

The Entity Framework and the Repository Pattern

The class EntityRepository<t> is the generic class used for repository access. The interface IRepository is used in all service constructs,
so we can use Dependency Injection to provide different implementations at run time. This release (29/12/2012) has changed significantly from the previous version
which all used concrete repository classes and restricted access based on the requirements of individual repositories. This approach removes a large number
of classes from the solution, simplifies the overall project structure, and improves the ease of unit testing.

The Domain Services

In VAL, the domain services are where most of the magic happens. The services here will perform a number of functions such as:

Tracing and logging

Parameter validation and exception raising

Repository access to perform data retrieval \ updates

The domain services have been designed with Dependency Injection in mind. A typical class signature for a service will read as follows. The DomainServiceBase class
gives access to some basic logging functionality to be shared by all service classes. The only construct on the service requires objects that implement IRepository,
which will allow us to test this service with fake data at a later point.

The last point is important, WCF will normally take care of creating service objects and it expects a parameterless construct. If we want to use the services with
StructureMap for Dependency Injection, then we need to be able to pass parameters to the construct. We therefore need a way of allowing parameters and having them wire
up with StructureMap automagically.

The good thing about WCF services is that they are highly customizable, we can create Service Behaviours, and configure our WCF environment to use them.
Between Jimmy Bogard
and Scott Griffin, I borrowed the solution they found for the problem. :o)

The four classes in the ServiceBehaviour folder (StructureMapInstanceProvider, StructureMapServiceBehavior,
StructureMapServiceHostFactory, StructureMapServiceHost) provide the functionality for wiring up WCF services to StructureMap,
allowing us to specify the dependencies to be injected into the constructs.

Dependency Chain

There is a dependency chain in the system that is resolved by StructureMap. When an instance of an object is requested, if it has a parameterised construct, then StructureMap will also attempt
to inject an instance of *that* object into the instance.

In VAL, the dependency resolution begins when a request to a WCF service method is received. This initiates a dependency chain that looks similar to this graphic.

Once the DataSettings class has been initialised, all dependencies are fulfilled and StructureMap is able to create instances of every object in the chain. It's important
to understand this concept, if there is an error in one of the classes deeper into the chain, it will cause an Exception in Structuremap.

Unit of Work Behaviour

Entity Framework 4.2 uses the new DbContext API, which is a 'Unit of Work'. During its scope (which is per HTTP request) we can make numerous changes
to the entities which are change tracked by the context. Until we call SaveChanges, none of these changes are actually committed to the database.
StructureMap will create this single instance per request and inject into any other object that requires an instance as part of its construct.

In order to aid testing and to ensure our services remain loosely coupled, we can abstract out the core functionality we require from the data context into a new interface,
IDbContext.

The method signatures for IDbContext allow us a way to retrieve and update data. The concrete implementation of this interface is then handled
in the DataContext (in project VAL.Data).

Service Behaviours

In order for StructureMap to create instances of the WCF services and resolve all dependencies, we need to attach the behaviour into the WCF service. We can apply this as part of the
service instantiation within our implementation of IServiceBehavior. The class StructureMapServiceBehavior implements this interface, and has a method body
for ApplyDispatchBehavior.

In the above code, we create an instance of ErrorHandler which provides our custom service behaviours. We attach the error handler
instance to the ChannelDispatcher and add new instances of StructureMapInstanceProvider to the InstanceProvider, this allows StructureMap
to intercept the request for the service and inject the required dependencies. Now, every time StructureMap is asked to create an instance of a WCF service,
it will apply our custom behaviours.

Service Contracts

In VAL, we control the codebase for both the client and the server - I wanted to share the definitions of the services between both.

I therefore created an assembly named VAL.Contracts that contains definitions of the service methods. A service interface will read similar to:

The Interfaces provide the contracts between the client and the server that allow them to communicate. The WCF services implement these interfaces and the client
can invoke these implementations using the WCFServiceClient code to locate the contract endpoints as configured in the client app.config.

Handling Security in the WCF Service

VAL is designed to be run in a secure 'trusted' environment such as a corporate network. Additionally, the information transferred by VAL cannot be classified as sensitive.
Therefore, we can choose a security model based on the following:

System security can be roughly grouped into 'Administrator' and 'Non Administrator' functionality

We don't need encrypted transport

We need to enforce group membership of the user account running the VAL client

We could use WSHttpBinding here, but for this model, BasicHttpBinding is fine. Much like the classic 'Web Service' model, we just need to call
a method and make sure that the user is allowed access to that method.

We can accomplish this by setting up the configuration bindings to transfer the user account details. However, we need to initialise the security credentials within the client proxy base.

This happens within the WCFServiceClient class in the VAL UI project. The client provides a custom implementation of ClientBase which allows us to set the credentials
and also provide a Dispose pattern for handling clean up.

Custom Security Attributes

Because security is a configuration value, we can keep the code clean by defining our own implementation of CodeAccessSecurityAttribute which allows us to read
a string from the config and apply that as the 'Require group membership' value.

The VALAdministratorsAttribute class constructs an instance of PrincipalPermissionExAttribute and instructs it to read the value
of AdministratorGroup from the config file. This value is then used to enforce the Security.Demand call.

Any permissions that fail are reported back to the client application as a SecurityFault.

Handling Faults in the WCF Service

There are a number of circumstances where the domain services will throw exceptions. One such example is object validation, which should occur on the client application
but will also happen on the server as part of 'Save' operations. If the object is invalid, an exception will be raised.

In cases where faults are expected, we need to return this information to the client so it can be displayed to the user. In all other cases, we want to log the exception
details on the server but shield the exception details from the user. Expected exceptions are caught by the WCF service and converted into Faults that are then returned
to the client. The client is responsible for catching and handling the expected Faults.

The Domain Model

The model was generated using the 'Reverse Engineer Code First' context menu that is available after installing
Entity Framework Power Tools. Once the entities
had been generated, a number of amendments were made.

All domain model objects inherit from PocoEntityBase

The PocoEntityBase class provides some functionality for enforcing simple instance rules and taking advantage
of the DataAnnotations syntax that is used in MVC. The class
has anumber of properties, Id, IsValid and ErrorMessage, that will allow you to check for broken rules and display the
appropriate error message to the caller.

To use this functionality, a Model class must have associated MetaData that provides the rules to be enforced. Due to the Model classes being generated by templates,
a bit of a hacky approach is used by creating Buddy Classes that provide only metadata in a separate
partial class. This allows you to auto generate your main model, while keeping your custom data annotations for model validation safe.

This MetaData is automatically wired into MVC, but in WinForms, we need to attempt to retrieve the MetaData ourselves. The DataValidator class exposes
a single method that will attempt to validate an object by wiring up its MetaData and calling the Validator.TryValidateObject method.

This keeps all of the 'simple' rules in one place in the domain model. Any consumers of our Model will have validation available to them with very little effort.
Our WinForms application enforces the rules in the following manner:

The Model classes really are the key to the system. They provide access to the data in strongly typed form, they form the basis of the messages to be transferred
over the wire, and they provide information about themselves to the client for validation.

WCF Service Invocation

Using svcutil, you can create client side proxy classes to invoke your service.

We can then change the generated class to use our custom base class that provides the security initialisation and Dispose pattern. The standard using pattern is
then adhered to when calling our service methods.

Unit Tests - Domain Classes

The last project in the VAL solution contains a number of unit tests. The tests make use of the Moq framework and some dummy data which we can query
and return results from using our existing domain services.

Within the unit test initialisation code, we create the Mock objects and Setup the repository methods to use our fake data:

In the above example test, we are ensuring that trying to save an object with the same WindowsIdentityName as an existing object will throw an exception named
UserAlreadyExistsException.

This is one of the major benefits of using a Dependency Injection framework such as StructureMap. The time we have spent creating loosely coupled domain
services using interfaces in our constructors is rewarded here, as we can send whatever test objects we like into the services and ensure the functionality within them works
as expected without requiring any underlying real data access.

Moq provides a simple and concise way to swap out the concrete implementations with Mock objects to ensure our service logic is correct and functioning as expected.

Unit Tests - WCF Services

A well as testing our domain classes, there are tests for the WCF service implementations. The WCF services have a different concern to the domain classes, so we only want
to test that they are doing their job as expected. We don't need to test 'over the wire' here, we can assume that this has all been tested by Microsoft! We just want to test
that our code is operating correctly.

In these tests, we can simply Mock the domain service return values - we don't need to test these again, that's all been done with our previous tests. We can follow
a strict Setup -> Act pattern for this stage of testing.

Consider the following test. All I want to test is that whenever an inactive user is requested, a FaultException is returned by the WCF service. We can therefore
setup the domain service to simply return an Inactive user object we create in the test. All we are testing here is that the exception is raised and returned as expected.

Beyond Code - Application Usage

Access Databases - Prior to Access 2007

VAL will help you manage Access database usage, particularly if you have databases being used in a thin client (Citrix \ Terminal Services) environment.

In Access 2007, Microsoft changed the security model for the new database format to remove user level security. However, Access 2007 is backwards compatible
and can still open the .mdb format and work with user security. A number of organisations are still using older versions of Office or have invested time
in creating user-level security based databases, so this functionality may still be useful.

VAL allows you to specify a Network workgroup. This should be an mdw file that is stored somewhere on your local network that all users of VAL would have access to.
The network workgroup is the central location where you would manage user accounts and group membership.

Access is notorious for data corruption, especially so in a thin client environment. Imagine that several users are all connected to the same Citrix Server,
which we'll call SERVER01. They haven't signed on to a particular workgroup and are all using the default user account which is 'Admin'. This means that Access will
attempt to create record locks for both the default system.mdw workgroup in the 'Microsoft Office' installation directory on SERVER01 and also
for the particular Access database. These are LDB files, which contain a record of the user and machine name locking the file and records.

Alarm bells should be ringing here. You have users all connected from machine SERVER01 all using the same credentials of Admin, sharing an ldb file
on a disk where Microsoft Office is installed! This is a recipe for disaster and can lead to corruption of both the Access database and the system.mdw file.

There are a few rules to follow when using databases in this setup to avoid data corruption.

Databases should be split into compiled front end (MDE) and data back end (MDB) files

Users should launch their own copies of the front end

Users should sign on through a workgroup

Users should sign on to the workgroup using a user specific account, not using 'Admin'

Users should sign on to their own copy of the workgroup

I've found that when using the above rules, data corruption of Access databases is at an absolute minimum.

VAL is geared towards helping out with this scenario; you can define applications as 'Access databases' and have VAL automatically distribute the compiled
front ends and workgroups to a user specific location. VAL will also attempt to sign the user on to the database transparently.

Workgroup Definition

For example, say you have your Network workgroup on a shared mapped drive, the Workgroup path may read something like K:\Public\AccessDatabases\Security\CompanyWorkgroup.mdw.

If you have defined your file in VAL as an Access database type and specified this workgroup, when you launch the Access database, VAL will take a copy
of the mdw file from the network location and put it in a location specific to the user. This could be in something like,
C:\Documents and Settings\username\Application Data\ or in any other location you like, as long as it is unique to the user.

VAL will then attempt to sign on via the copy of the workgroup which will now only ever contain one record lock for the individual user.
VAL will also pass the Environment.UserName to the workgroup sign-on and attempt to sign the user into the workgroup. This ensures that the LDB
file for the Access database contains information such as SERVER01 DMORLEY, SERVER01 ANOTHERUSER, SERVER01 THIRDUSER.

By forcing the user to sign on using their account name, the shared LDB file for the Access database will contain unique user identifiers, even when using the same server thin client.

Access Permissions

Managing access permissions can be a tedious process. If you setup a user in VAL, ensuring that the user is also created in your Network workgroup and assigned group membership
adds another layer of complexity.

VAL allows you to clone a new user from an existing user. As well as creating all the icons for the user, it will attempt to copy Access database permissions from the source user,
ensuring that the user account and permissions are all correctly assigned.

This is achieved through ADODB and ADOX; please see the source file WorkgroupHelper which uses Reflection to 'late-bind' the COM functionality. Use the 'New User'
wizard to step through the cloning process.

Access Databases - Summary

The workgroup settings for the Network workgroup should be defined in the app.config VAL settings for enterpriseWorkgroupDirectory
and enterpriseWorkgroupName. Only define these if you are using legacy Access database security models, otherwise they can be left blank.

Internet links

VAL is also useful for distributing web site addresses as icons. For example, you may have a number of in-house intranet applications that can be accessed from particular URLs.
Individual users have to keep a record of these URLs in something like their browser favourites.

In VAL, you can create a new file and select the browser to launch, e.g., C:\Program Files\Internet Explorer\iexplore.exe. VAL will automatically retrieve the Internet Explorer
icon and assign it to your file. Now you can replace this with any image of your choice and then create an entry in the command line section of the file maintenance screen and point
it at any URL you like. Imagine we wanted an icon for the 'CodeProject', you would enter http://www.codeproject.com/.

When VAL attempts to launch this, it will build the following string to start
the application: "C:\Program Files\Internet Explorer\iexplore.exe" http://www.codeproject.com/.

This is a very simple way of delivering web applications to users as an Icon that represents your link. If any of the URLs change, you have a central location to maintain the data.

Distributing Files - General

You can always distribute files, regardless of the underlying file type. As long as the account running the VAL client has access to the location specific in the File Maintenance screen,
it can take a copy of the file and place in another location.

There are various reasons for wanting users to launch via a file copy, VAL lets you manage this easily.

Summary

This is a summary of the architecture of the Visual Application Launcher and its possible uses. As mentioned at the start of the article, it's an over-engineered solution
for such a simple application, but the real purpose here is to show how we can use various tools at our disposal.

Acknowledgements

Like most programmers, I learn a lot from Internet resources and example projects. A lot of the code in this solution can probably be found on the Internet in certain forms.
Where I've used complete classes, any headers and credits will point you to the original authors. In other cases, I've found snippets and solutions on message boards and incorporated
them into larger classes. In these cases, I can't credit everyone because I've forgotten where everything came from!

A big thank you to people who take time out of their busy schedules to answer questions, point us towards resources, or simply make projects Open Source.

To Do

The next step here is to create a WPF front-end rather than WinForms and have it consume the same service model. That'll be in a future article :)

History

29/12/2012 - Entity Framework update and code simplification.

Updated Entity Framework to version 4.2 'Code First' syntax.

Removed repository project \ Unit of Work implementation. Now using single generic repository and DbContext API.

Removed all concrete repositories and repository traits. Much simpler and cleaner approach.

Added NuGet packages.

Added Moq framework and updated all tests to use Moq.

15/9/2011: Updated article to reflect changes made on 24/6/2011.

Removed WCF Service Invoker and ChannelFactoryManager details, now obsolete.

Added details about Unit of Work per Request pattern and how this is controlled from StructureMap.

Added information about custom security attributes.

24/6/2011: Major changes to the overall structure of the project.

Added an implementation of IDispatchMessageInspector to handle 'before' and 'after' WCF events.

Unit of work now controlled through the IDispatchMessageInspector, a 'unit of work per request' approach. Simplifies code in the actual WCF service.

Simplified WCF Services into two svc files, one 'User' service and one 'Administrator' service.