blog community

Welcome to blog community Sign in | Join | Help
in Search

Willem Meints

Deleting browser cookies ... Best done with a glass of milk

  • Introducing the dialog workspace for Composite WPF

    Vacation is the best time to solve some serious puzzles, at least it is for me. The problem I was having with Composite WPF was the fact that I could create composite user interfaces, but there wasn't any support for showing views in dialogs. And because dialogs are widely used I had to come up with a fix for this.In this post I will talk about what the DialogWorkspace class is and how I created it.

    What is the dialog workspace?

    The dialog Workspace is a class that provides developers with a way to show any view inside a OK/Cancel dialog. This way you can work with a model view presenter pattern and don't have to worry about common infrastructure for the dialog itself. It saves time and you don't have to worry about bugs in the window infrastructure.

    Creating a dialog container for a view

    The first part of the solution is creating a way to actually show a view inside a dialog. For the first version of the dialog workspace I went with a simple dialog that has a OK and Cancel button on it and some room for the view itself. Pretty simple, but there are a few things that you need to keep in mind when creating the dialog:

    • How high?
      The view that is going to be displayed in the dialog doesn't have the same size all the time. Every view has its own dimensions and you need to provide a way to resize the dialog to the content. The solution is again simple. By setting the ResizeToContent=WidthAndHeight attribute on the window you can let the window resize when the view is bigger or smaller.
    • Usability
      There's nothing more irritating than not being able to use ENTER to accept the dialog and ESCAPE the cancel the dialog. Most of the time users who use the dialog will want to enter the data quickly and press ENTER to accept the results. This functionality is enabled by setting IsDefault=true for the accept button and IsCancel=True for the cancel button. When the user now presses ENTER or ESCAPE the right button will be "clicked".
    • The paintjob
      WPF does everything in white, at least all the windows are white. But as most developers may know, Windows isn't painted all white. For the most part it has battleship gray in Windows 2003 and a fancier color in Vista and Windows XP. To achieve this you need to add this attribute to the Window element: Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"

    The workspace

    It looks like a really complex class, but it really isn't. The DialogWorkspace class is a static helper class that will configure the dialog and handle the validation logic for you. In this first version it is only possible to provide a view and a delegate to a validation function for the dialog. In the next version I will include more options.

    The method that shows the dialog and handles the validation logic looks like this:

    /// <summary>
    ///
    Displays a view in the dialog workspace
    /// and returns the dialog result after the dialog has been closed
    /// </summary>
    /// <param name="view">
    The view to display</param>
    /// <param name="validationAction">
    Validation function for the view</param>
    /// <returns>
    Returns the dialog result of the dialog</returns>
    public static bool? ShowView(object view, Func<bool> validationAction)
    {
    ViewDialog dialog = new ViewDialog();
    dialog.View = view as DependencyObject;

    dialog.ValidateDialog += new EventHandler<System.ComponentModel.CancelEventArgs>(
    (sender, e) =>
    {
    e.Cancel = false;

    if (validationAction != null)
    {
    // Validate action will return false when validation fails
    // invert this result to cancel the close action
    e.Cancel = !validationAction();
    }
    });

    return dialog.ShowDialog();
    }

    Using the Dialog Workspace

    Due to the structure of the dialog workspace it is not really that easy to test this component. So instead of creating a unit-test I created a very small WPF application that shows a dialog using the DialogWorkspace class with validation functionality attached. The sample application demonstrates how easy it is to show a view and handle validation logic. The following snippet demonstrates the basics of showing a view as a dialog in the application.

    ISampleViewview = _container.Resolve<ISampleView>();
    bool? result = DialogWorkspace.ShowView(view,() =>
    {
        return true;
    });

    if(result == true)
    {
       
    }

    Download and more information

    As always you can download the latest changeset from http://www.codeplex.com/compositewpfcontrib You can also find more information there on other extensions for Composite WPF.

  • TypeForwardedTo Attribute

    It’s the little things that make working with .NET fun. Especially the sometimes not so useful documentation or classes you never knew existed. I was surprised  to discover that Microsoft has a TypeForwardedTo attribute to indicate that a type has moved from one assembly to a new assembly.

    Read all about it here: http://michaelsync.net/2007/07/30/what-is-typeforwardedtoattribute

  • Use case controllers, container hierarchies and services in composite WPF

    Composite WPF comes with the notion of modules, but without any standard classes for controllers and/or viewmodels. This might sound weird to developers who have worked with the Composite Application Block before. In this post we will talk about how you can create them yourself and why base classes for these constructions aren't actually required.

    Introduction to the use case controller

    Often you implement use cases inside a controller that shows and hides all the required user interface parts and lets you navigate through the steps of the use case. It's the central part of the use case. In Composite WPF Microsoft took extra care to make it possible to create controllers with zero interference from user interface components or any framework components for that matter.

    In fact, the use case controller in Composite WPF is nothing more than a class on which you can invoke a method to start the use case. The rest is a matter of letting the controller handle all the required logic. There is no need to derive from any base class whatsoever.

    What if you need stuff from composite WPF

    Often just building the controller isn't enough and you need services offered by Composite WPF or services that you have registered on the IoC container in the application. At this point it's good to know that you can make use of unity to let it inject the required components in the controller. A sample of a class utilizes this principle is shown below.

        1 public class CreateProjectController

        2 {

        3     private IUnityContainer _container;

        4     private IEventAggregator _eventAggregator;

        5 

        6     /// <summary>

        7     /// Initializes a new instance of the CreateProjectController class.

        8     /// </summary>

        9     /// <param name="container"></param>

       10     public CreateProjectController(IUnityContainer container)

       11     {

       12         _container = container.CreateChildContainer();

       13         _eventAggregator = _container.Resolve<IEventAggregator>();

       14 

       15         RegisterTypes();

       16     }

       17 }

    Initializing the controller can be done with one line of code:

        1 /// <summary>

        2 /// Starts the create project use case

        3 /// </summary>

        4 /// <param name="arg"></param>

        5 void CreateProject(object arg)

        6 {

        7     CreateProjectController controller = _container.Resolve<CreateProjectController>();

        8     controller.CreateProject();

        9 }

    The interesting part here is the fact that I created a child container for the controller instead of using the controller provided in the constructor. I will get back to that in a second. This small piece of code can be extended further to retrieve for example the event aggregator service or the module loader.

    The use of child containers

    The reason why I created a childcontainer is because this allows me to implement a wide variety of scenarios that are often required inside applications. One of the things that you can do is have a registered type that has a single instance per container. This may sound not so useful, but what if you needed a single instance for each time you started a use case. You can't do that without the use of a child container.

    How container hierarchies work

    Unity supports container hierarchies by creating child containers. This allows you to isolate type registrations from other containers. When resolving a type from the container unity will first try to resolve the type in the current container. If the type is not found in the current container, unity will move up one level in the hierarchy and tries to resolve the type there. This continues up to the root container.

    So if you register a type in the root container, it is available in all child containers, however if you register a type in a child container it is not available in a container on the same level or in a container higher in the hierarchy.

    General tips

    There are some general tips and tricks that can help you get more out of this construction. Here's a list:

    • Register global services in the root container
      By registering services in the root container you make them available to all modules in your Composite WPF application. Just make sure you reference the contract of the service in the modules where you need the service and you have a great service locator.

    • Make use of the ContainerLifecycleManager class
      When you need a singleton instance of a class you can register an instance of the type, however this requires you to create the instance of the class at the moment you register it as a singleton. You can conserve memory by registering the type with a new instance of the ContainerControlledLifetimeManager. This makes the type a singleton in the current container. If you do this at the right level you can control where the singleton instance is available.

    • Using the container is a good thing, but don't overdo it
      Creating instances of classes through the container can be useful, especially if you need to inject several dependencies. However don't use the container as a generic factory for all objects. Instead take a good look if you need to create the instance through the use of the unity container and don't use it if you don't have to.

    Conclusion

    The unity container is essential to Composite WPF and a very powerfull tool when used correctly. I hope this article helped getting a better picture of it's use in combination with use case controllers.

  • Using ADO.NET Entity framework with the repository pattern

    Microsoft released the ADO.NET entity framework with their latest service pack and I’m quite happy with what they have done so far. The entity framework helps reduce code complexity for creating entities and it also saves you the work of having to write all the mapping code yourself.

    One of the things I tried out was to use the Repository pattern (Well known to the NHibernate community) to make the framework easier to use by reducing the amount of methods that are available.

    First attempt

    The first attempt was pretty straight forward. Create a new model and two repositories that access the various entities in the model. I used interfaces here to maximize testability. You can of course leave the interfaces out if you don’t want the clutter in your code.


    As part of my first design I used a single object context with each call inside a using statement, this ensures that the garbage collector cleans up after I’m done thus reducing the amount of memory needed. However this caused some really weird behavior when building the following scenario:

    I have a method that creates a new task and attaches it to a project. The project is retrieved from the project repository class and the task is created by task repository. After the task is created the program calls the save method on the task repository to save the task. You’d think that this works perfectly. At least I thought this would work.

    What really happens is that as soon as you attach  the project instance to the Project property of the task, the task is registered with the object context of the project. That object context is now tracking the changes and correctly detects that the task is new and should be added when SaveChanges is called on the object context. However, I am not calling SaveChanges on the object context of the project, but rather on the Task object context. The task is not tracked by that context and thus not saved to the database.

    Improved design

    The first attempt left me with a rather large hole in my design. Clearly this wasn’t the only scenario where this would go wrong, so I had to change something to make it work. It’s a trade-off in memory usage, but if you move the object context to a central static class and let the repository classes use that instance the problem is solved. The new design looks like this:


    There’s one catch though. You have to manually dispose the object context once the application exits. Or in the case of a service, dispose the context once you have constructed the reply message and no longer need the object context.

    Conclusion

    The object context in ADO.NET Entity framework is a great way of working with the entities and keeping track of changes made to any of the entities. However it will give you a major headache when you don’t have a single object context for the whole domain model. Having one object context isn’t all that either, because hanging updates from one operation will most likely cause problems when performing the next operation. I have seen this too and I haven’t got a solution for that at the moment.

    I hope this helps to prevent some of the troubles that developers have when they start using ADO.NET entity framework for the first time.

  • Cool new features in WPF 3.5 Service Pack 1

    Microsoft has released a new service pack for .NET 3.5 and Visual Studio 2008, containing some pretty cool features. A lot of them can be found in WPF which has gotten quite a few fixes and additions that are really useful for developers who are using WPF today.

    In this post I will show some of the interesting new features, not all will be explained that detailed, but it's more to get an idea of what is going on. The most interesting features will be shown here, others can be found on MSDN.

    Splashscreen

    The startup of WPF applications is kind of slow, especially when you perform a cold start. For really large applications this isn't really a problem in my opinion (I can hear you think: What is he talking about?!?). The slow startup with large applications is understandable for users, but it is always best to have the application startup fast with a splashscreen or something, just to let the user know it all works and he just needs to be patient for the application to start.

    Microsoft introduced the splashscreen build action for this. You can add any kind of static image to your application and set the build action to SplashScreen. What the compiler will do is create a new splashscreen for the application based on the image and display it when the application starts. Pretty cool if you ask me.

    Note: The splashscreen does not support XAML or anything that animates. Also note that the cold startup does not actually improve. The image will show rapidly, but the main form still requires a bit more time to load.

    Improved debugging experience

    The debugging experience is improved greatly with SP1. Before this service pack, errors in the XAML were either displayed without any reference to the code or were displayed within the code that was generated from the XAML. Both solutions weren't really all that and I was quite frequently frustrated that stuff was showing up so badly in the debugger.

    With SP1 things have improved and stuff that is wrong in the XAML is shown in the XAML where it belongs. This is a big step forward and will make life a lot easier for developers.

    Improved refactoring support

    Refactoring support is an important feature for me as I first build a very raw prototype UI and refactor that prototype into something that I can work with and is more easy to maintain. During this process I move stuff around, rename things and delete things. Previously you had to manually keep the XAML and code in sync when renaming stuff. Not anymore, Microsoft made it possible to rename stuff in code and the same component is also renamed in the XAML.

    Performance

    There's more things in the performance area that are improved with the servicepack. The first thing they did was the splashscreen, although not actually a performance improvement, it does show an increase in perceived performance to the user. Which is of course important too.

    The other performance improvements are largely found in rendering of text and effects. More effects are now hardware rendered and they have included an api to write your own shader effects, which can be rendered with any 3D graphics card that supports them.

    Data and Databinding support

    One of my favorite areas in WPF is databinding, it's so easy to bind objects to the user interface that I can't live without it. Windows Forms simply doesn't cut it for most tricks I perform in WPF with databinding. They improved quite a lot in this area

    • Alternating rows in controls derived from ItemsControl (Which are a lot of controls)
    • IEditableCollectionView - Makes it possible to edit items in a collection view in a transactional manner
    • StringFormat support in {Binding} expressions, previously you needed to use a value converter for this, but now it's buildin

    Direct3D

    Last but not least, they added interoperability support for Direct3D. I'm not much of a 3D guy, so I take this one for granted and will take a look at it once I've got to use it ;P It looks pretty neat, you can map 3D scenes rendered in Direct3D on to images or even textures in WPF. This allows for more cool scenarios and new ways to present information to the user.

    Conclusion

    Microsoft could have called it WPF 3.6, there's loads of new stuff included, most of which developers of rich business applications will most likely use as soon as they start building WPF applications. I think we can congratulate the WPF team on yet another great release.

  • Datagrid control for WPF

    One of the things that was missing from the first releases of WPF was the datagrid control. Microsoft reasoned that you could create your own grid using the existing components. I won’t argue the fact that it is possible, but it isn’t an easy task and I agree with other WPF developers that Microsoft could have included the datagrid in the WPF release.

    The good news is that Microsoft is hosting a new codeplex project for WPF, which contains a brand new DataGrid control. It’s a CTP, so don’t expect a bugfree experience, but it’s a good start and there’s sourcecode available if you want to change stuff yourself.

    The project is located here: http://www.codeplex.com/wpf

  • Tired of using XML all the time?

    Sometimes XML configuration can be really cumbersome, you need a ton of .config files and .xml files to even get a small application running. It seems as if the xml fetish has come to a point that people start to get annoyed and start looking for alternatives.

    Use of configuration files in practice

    Before I start talking about how I think configuration can be approached, I’d like to show some examples from the industry on how configuration files are used and what alternatives the industry is providing today.

    For example NHibernate uses NHibernate mapping files to map classes to tables in the database. You need one file per class, so when you build a decent sized application this will soon get to at least 20 – 60 files. Alternatively you can make the configuration in code using Fluent NHibernate, which eliminates the need for XML configuration entirely. Note though that this doesn’t solve the problem of having to specify the mapping for all those classes in some way.

    Then there is CompositeWPF, there you can choose to use the XML module enumerator class for configuring which modules should be made available in the application, however this requires you to write a ton of XML to get the modules configured, with all the risks of not getting the application working. Alternatively you can use the Directory module enumerator and be done in a jiffy.

    A very good example of how you can setup configuration from code in my opinion is Unity. The configuration is done from code, so users can’t mess up the internal workings of the application. One really disturbing note however is that you can influence this configuration using a special configuration section in the app.config file.

    General toughts

    In general I think that using XML for configuration isn’t a bad thing, however it can get out of hand. The worst example of this is stuff that shouldn’t be visible to the user, because it’s configuration needed for a framework that is strictly meant to make life easier for the developer. Configuration for these kind of components should generally be in code. The reason for this is simple: The developer is used to working with code and moreover, you get free compile time checks if the API for configuring the framework was written correctly. The end result of this is higher quality software and less frustrated users.

    There is a category of configuration data that changes more often and should be accessible to the user who deploys the software and uses the software on a dayly basis. Some of the settings that should be editable by the user can well be placed inside XML files or .config files. A database connection string that is configured only once for example should belong inside a .config file and should be updatable when required. In this case XML is great, because system administrators almost immidiately understand the format and can start editing the config file without having to decode complex constructions.

    Last but not least, there’s a category of settings that should be easily accessable through the user interface. The user should be able to change these settings without restarting the application. I think it’s rather frustrating having to close the application before I can update something simple like the path of a project file I’m working on.

    Final thoughts

    Like the voiceover on animal planet ssay: Please do give a thought where you configuration goes (Err.. I think she meant rubbish). It will make your application not only more maintainable, but also prevents users from making mistakes that they shouldn’t be possible to make in the first place.

  • Getting latest files from TFS using PowerShell

    Since not all our files that are in TFS source control are used from Visual Studio it’s kind of overdone to start visual studio for getting the latest version of a SQL script. However, working with tf.exe is somewhat cumbersome too. The shear amount of commandline parameters got me wondering why I didn’t have a powershell script to make the task of getting the latest version of a file a little easier.

    The following powershell script can be dot-sourced (Will talk about that in a minute) so you can just invoke Get-LatestVersion from the powershell console to get the latest version of all files in a particular folder and subfolders.

    function Get-LatestVersion() {
        $location = get-location
        tf.exe get $location / version:T / recursive / force
    }

    To use this function from powershell, you can save the fragment to a ps1 file and invoke the script using the following commandline:

    . TFSExtensions.ps1

    Note the dot in front of the script, this means that powershell dot-sources the function. By dot-sourcing the script gets imported in the runspace of powershell so that it is available during the time you have that powershell session open.

    For even easier access I added the dot-source command to my profile script, so the extensions get loaded each time I run powershell.

  • Returning raw XML from a REST WCF Service

    One of the new features in WCF for .NET 3.5 is the possibility to create REST Services. These services allow you to create services that eat raw HTTP requests with XML in them and return a raw HTTP response with XML content in them. Normally this only works by deserializing objects and serializing objects. It is however perfectly possible to return raw XML.

    For this to work you need to have the base class Message as the return type for your webmethods. Furthermore you are going to need the following helper class to write raw XML content to a message body.

    public class XmlElementBodyWriter : BodyWriter
    {
        XmlElement xmlElement;
    
        public XmlElementBodyWriter(XmlElement xmlElement)
            : base(true)
        {
            this.xmlElement = xmlElement;
        }
    
        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            xmlElement.WriteTo(writer);
        }
    }

    Creating a raw XML document and returning that object is just a matter of invoking the helper class with the right information. This can be done using the following small piece of code:

    private Message CreateResponseMessage(XmlDocument inputDocument)
    {
        XmlElementBodyWriter writer = new XmlElementBodyWriter(inputDocument.DocumentElement);
    
        Message msg = Message.CreateMessage(MessageVersion.None, 
            OperationContext.Current.OutgoingMessageHeaders.Action, writer);
    
        return msg;
    }

    This trick is especially useful when you want to upgrade an existing webservice to a REST service and that service returns raw XML documents as the result of a web method. Enjoy :)

  • .NET is not always that useful

    Please don't start e-mailing me that I am wrong here, for the most part .NET is a great framework and it contains a lot of useful components. Except for the GridTablesFactory class. I have no idea what it does and appearantly Microsoft isn't so sure either.

  • Creating closeable tabitems for use in CompositeWPF

    Using a tabcontrol as a region for views in a CompositeWPF application is one thing, making them closeable can be a bit trickier. The sample in this article will show how you can modify a tabcontrol to allow closeable items.

    Step 1: Make the custom header template and tabitem style

    The first step is to modify the look of a tabitem header so it contains a close button while leaving room for the header content defined on the tab item. The XAML content required for this looks like the following:

    <TabControl>
    <TabControl.Resources>
    <DataTemplate x:Key="CustomTabHeader">
    <StackPanel Orientation="Horizontal">
    <ContentPresenter>
    <ContentPresenter.Content>
    <Binding Path="Header">
    <Binding.RelativeSource>
    <RelativeSource Mode="FindAncestor"
    AncestorType="{x:Type TabItem}"/>
    </Binding.RelativeSource>
    </Binding>
    </ContentPresenter.Content>
    </ContentPresenter>
    <Button Margin="8,0,0,0" Command="local:Commands.CloseTabItem" CommandParameter="{Binding
    RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type TabItem}}}"

    HorizontalContentAlignment="Center"
    VerticalContentAlignment="Center">
    <Grid>
    <Canvas Width="8" Height="8">
    <Line X1="2" X2="6" Y1="2" Y2="6"
    Stroke="Black" StrokeThickness="1"/>
    <Line X1="6" X2="2" Y1="2" Y2="6"
    Stroke="Black" StrokeThickness="1"/>
    </Canvas>
    </Grid>
    </Button>
    </StackPanel>
    </DataTemplate>
    <Style TargetType="TabItem">
    <Style.Setters>
    <Setter Property="HeaderTemplate"
    Value="{StaticResource CustomTabHeader}"/>
    </Style.Setters>
    </Style>
    </TabControl.Resources>
    </
    TabControl>

    Step 2: Closing tabitems

    The second step is writing a little bit of code to close tabitems when the command is fired.

    private void OnCloseTabItemExecute(object sender, ExecutedRoutedEventArgs e)
    {
    TabItem parent = e.Parameter as TabItem;

    if (parent != null)
    {
    FrameworkElement view = (parent as TabItem).Content as FrameworkElement;
    string regionName = RegionManager.GetRegionName(view);

    _regionManager.Regions[regionName].Remove(view);
    }
    }

    The first thing to do is find the tabitem that is quietly wrapped around the view that was added to the tabcontrol. This is done through a recursive search for parent framework elements until the tabitem is found. After that its a matter of retrieving the value of the RegionName attached property and removing the tabitem content from the region.

    Conclusion

    While a custom may look prettier over time it’s really not a requirement to make closable views in a compositeWPF application. Thanks to the powerful styling and templating features in WPF you can make the tabcontrol as fancy as you like without making it overly complex to work with.

     

    -- Update : The sample didn't work as expected. I have updated the sample code and made sure it works now. Please notify me if any more issues arise.

  • Silverlight and ADO.NET data services gotcha

    Most people who know me, also know that I like to fiddle with technology in my own free time. It's one of those things that I simply can't let go, maybe later but certainly not at the moment.

    One of the things I'm currently quite enthuisastic about is the new version of Silverlight. Microsoft has finally come up with a technology that combines web, wpf and the flexibility offered by .NET. Since I got so much to do with CompositeWPF and WPF in general I thought I'd give PrismAg a try and build my self a photoviewer silverlight app, combining a lot of stuff that is bound to give me a puzzle ;)

    Let's get to the point here. I created a silverlight application and a ADO.NET data service and connected the two so that I could display album and photo information from a database I already got running for another sample. Thinking this would work right away I fired up the debugger and got a nice error served up telling me that a javascript call failed.

    This got me wondering quite a bit, because I only wrote C# and a bit of XAML. So where does the javascript come from? As it turns out, Silverlight generates javascript to work with ADO.NET data services and the error I got was because I violated the cross domain policy.

    The moral of the story? Always check documentation and always services that are on the same host as the silverlight application. You can use external services, but only if you created your own proxy. It isn't pretty, but it will save you two hours of puzzeling ;P

    -- UPDATE: I thought silverlight was generating javascript for the call to the service, but it turns out that it generates javascript to report the error to the client browser. They have hard coded limitations in the mechanics to do webservice calls and http calls, so you can't do anything that would cause a security problem.

  • CompositeWPF – Installing modules on demand

    One of the very cool features of modular application in my opinion is the possibility to install features when they are actually required by the application. Microsoft uses this since Office 2000 to provide the user with the possibility to install a module on demand when the module is marked install on first use.

    To make on demand installation of modules possible in a CompositeWPF application I created an extended version module loader service. In this post I will show how you can integrate Windows installer functionality and build the module loader service yourself.

    Integrating Windows Installer

    One of the key parts of installing modules on demand is creating a way for a CompositeWPF application to talk to Windows Installer. This involves some win32 hacking by importing functions from msi.dll into the application.

    Windows Installer provides a way to query the status of a feature by calling MsiQueryFeatureState providing the productcode and the name of the feature you want to know the status of. The result of this method is a value in the InstallState enumeration where Local or Default indicates that the feature is actually installed and Absent that the feature is not available at this moment. Microsoft uses Advertised to indicate that a feature has to be installed on first use and I did so too. The DLL import required here looks like this:

    /// <summary>
    /// Retrieves the install state of a specific feature
    /// </summary>
    /// <param name="productCode">Product code of the product
    /// <param name="featureName">Name of the feature
    /// <returns>Returns the install state of the product
    [DllImport("msi.dll",EntryPoint="MsiQueryFeatureState",CharSet=CharSet.Unicode)]

    The second functionality required is a way to actually install a single feature. This is done by invoking MsiConfigureFeature providing the productcode, the name of the feature you want to configure and the target install state. Although you can specify quite a lot install state values here I recommend to use InstallState.Local to get the feature installed. This will install the feature for the local user. The DLL import required for this looks like this:

    /// <summary>
    ///
    Configures a feature of the specified application
    /// </summary>
    ///
    <param name="productCode">Product code of the application</param>
    ///
    <param name="featureName">Name of the feature to configure</param>
    ///
    <param name="state">Install state to configure</param>
    ///
    <remarks>
    ///
    The following install states can be configured:
    /// <see cref="InstallState.Local"/> Feature will be installed locally
    /// <see cref="InstallState.Absent"/> Feature will be uninstalled
    /// <see cref="InstallState.Source"/> Feature will run from source
    /// <see cref="InstallState.Default"/> Feature will be installed to default location
    /// </remarks>
    ///
    <returns></returns>
    [DllImport("msi.dll", EntryPoint = "MsiConfigureFeature", CharSet = CharSet.Unicode)]
    public extern static uint ConfigureFeature(string productCode,
    string featureName,
    InstallState state);

    Building the extended module loader service

    Once you have the windows installer integration working it’s quite simple to create a custom service that ties the windows installer features and the CompositeWPF features for loading modules on demand together.

    The functionality to load the custom module looks like this:

    /// <summary>
    ///
    Loads a single module and installs it if it is
    ///
    installed and the installIfNotAvailable parameter is set to true
    ///</summary>
    ///<param name="moduleName">Name of the module</param>
    ///
    <param name="installIfNotAvailable">Whether to install the module if available</param>
    public void LoadModule(string moduleName, bool installIfNotAvailable)
    {
    if(String.IsNullOrEmpty(moduleName))
    throw new ArgumentNullException("moduleName");

    IModuleEnumerator moduleEnumerator = _container.Resolve<IModuleEnumerator>();
    ModuleLoader moduleLoader = _container.Resolve<ModuleLoader>();
    // Retrieve the required module information
    ModuleInfo module = moduleEnumerator.GetModule(moduleName);

    if (module == null)
    {
    throw new ArgumentException("Requested module was not found",
    "moduleName");
    }

    // Check if the module should be installed
    if (installIfNotAvailable)
    {
    InstallState installationState =
    WindowsInstaller.GetFeatureState(_productCode,moduleName);

    if (installationState != InstallState.Local &&
    installationState !=
    InstallState.Default)
    {
    // Make sure that the feature is installed locally
    WindowsInstaller.ConfigureFeature(
    _productCode, moduleName,
    InstallState.Local);
    }
    }

    // Initialize the module
    moduleLoader.Initialize(new ModuleInfo[] { module });
    }

    First the service looks up the module in the application. This is required to check if the module actually exists at all. You can also use the QueryFeatureState method for this and check for advertised, but I choose to use this method as it more definite in my opinion. The next step is checking if the module is installed, this is only done when the installIfNotAvailable flag is active, otherwise it will just go on and try to initialize the found module.

    More information and download

    More information can be obtained from the following sources:

  • Running ASP.NET websites from the Global Assembly Cache

    Running ASP.NET websites from the GAC was always something I wanted to try out, because with 40 websites running exactly the same code there must be a better way to deploy them. So last week I tried it out and to my surprise it worked right away. Here’s how to do it with your own websites

    Step 1: Sign the website assembly

    Before you can place assemblies in the GAC you have to sign them. With websites this can be a bit more difficult to achieve. There’s just one requirement  for this to be possible: Use the web application project type as the basis for your website.

    When you use the web application project type you get an extra tab in the Properties of the project that says “Signing”. There you can provide a strong-name keyfile to sign the application. After that it’s a matter of doing a rebuild and you have strong named assemblies.

    Step 2: Make a separate deployment structure

    Since the website will be running from the GAC you will need a different deployment structure. I used the following structure which worked great:

    • Application root
      • Bin
      • WebApp

    I used a separate bin directory where I placed all the assemblies required by the application. From there they are deployed in the GAC. The WebApp contains all aspx pages, css files and other files required for ASP.NET, but not a bin directory.

    This structure can be expanded to allow multiple copies of the webapp directory with a different web.config. It’s not the prettiest structure when you have 40 websites, but hey the application is 7 years old, so we can’t modify the internals that much, that we can run multiple websites with the same aspx files.

    Step 3: Modify web.config

    One of the trickier steps in the process is changing the web.config so that the assemblies required for compilation of the aspx pages can be found. One of the utilities that will come in handy here is the sn.exe utility.

    The <compilation> section in web.config contains the assemblies required for the compilation of the aspx pages in the website. This is where all the assemblies from the web application should be registered. The section looks something like this:

    <compilation debug="false">
      <assemblies>
        <add assembly="MyAssembly, version=1.0.0, culture=neutral, publicKeyToken=null"/>
      </assemblies>
    </compilation>

    For each assembly directly referenced by the application you should include an <add> construction in this section. All other assemblies that are dependencies of the assemblies directly referenced by the application should be available from the bin directory specified earlier, but can be omitted here.

    While not required you can also extract all the prefixes for custom controls from the pages and place them in the configuration file. This will make the website more maintainable, because you don’t have the prefixes and assembly references for the controls all over the pages in the website. To register the prefixes in the web.config you should modify the web.config file so that the <pages> section looks like this:

    <pages>
      <controls>
        <add tagPrefix="custom" namespace="MyNamespace" 
             assembly="MyAssembly, version=1.0.0, culture=neutral, publicKeyToken=null"/>
      </controls>
    </pages>

    Step 4: Registering the assemblies in the GAC

    The last step to get the website working involves registering the assemblies in the global assembly cache. Lazy as I am I created a powershell script to make this a quick and easy task. The script looks like this:

    ls -filter *.dll -recurse | %{ gacutil -i $_.FullName }

    Conclusion

    While not really straightforward at first this can make the life of website sysadmins a whole lot easier and save on deployment costs. Also using the control prefix registration in web.config will make the website better maintainable. All things considered I think that running from the GAC is a pretty cool feature of ASP.NET and recommend for scenarios where you have about 25 websites or more on one server.

  • Module status service for CompositeWPF

    CompositeWPF offers modularity by making it possible to load modules from disk on demand or loading a set modules at startup of the application. One thing that I was missing with this was the possibility lookup the status of modules and which modules are actually available to the application at the moment.

    To solve this I wrote a new extension on CompositeWPF that offers the possibility to query a Module status service for a list of available modules and the status of each module.

    Usage

    To use the module status service you need to add some custom logic to you UnityBootStrapper instance. (Sorry folks, no support for other IoC containers at this moment yet).

    The first step is to register a new unity extension with the unity container. This extension will add a new builder strategy to the container. This new builder strategy is placed in the very last stage of object construction and registers the type of the constructed object as loaded module when the constructed type is an instance of IModule.

    The next step is registering a singleton instance of the Module Status Service so that the application can use this service to retrieve status information about modules. A sample on how to configure the container for the module status service is shown below:

    /// 
    /// Configures the container.
    ///
    protected override void ConfigureContainer()
    {
    base.ConfigureContainer();

    Container.AddExtension(new ModuleTrackingUnityExtension());
    Container.RegisterInstance(Container.Resolve());
    }

    After you have registered the module status service with the required container extension you can module status information by invoking the following code:

    IModuleStatusService service = Container.Resolve();
    ReadOnlyCollection modules = service.GetModules();

    How does it work

    The solution is composed of two parts, one is the module status service which is used by the application to retrieve module information. The other part is the module tracking extension for unity.

    The Module status service

    The module status service is pretty straight forward, it has an internal list to keep track of loaded modules and two methods. One method to register a loaded module and a method to retrieve a list of modules.

    The LoadModules method is interesting as it makes use of some internals of the CompositeWPF framework. One of the things CompositeWPF does when you use the UnityBootstrapper, is registering the module enumerator that was supplied in the container. This module enumerator is now available to other components in the application.

    You can use this module enumerator in the module status service to retrieve a list of modules that you can expect to be available in the application.

    Retrieving a list of modules is quite easy using this technique, but you can’t really see if the module has been actually activated if it is in the list of modules retrieved from the module enumator. For this you need the module tracking extension.

    Module tracking extension

    The module tracking extension for unity contains some magic to keep track of modules that are being loaded. There are actually two things that happen here:

    1. A new builder strategy is added to the object builder chain
    The new builder strategy checks if the type being build is a module and registers the type of the object being constructed if it is indeed a module. This builder strategy is added as the very last strategy in the chain, this ensures that all construction logic is performed with success and the module is guaranteed to be activated.

    2. The RegisteringInstance event is bound
    Although not very likely it is possible to register module instances with the unity container using the RegisterInstance method. For 100% coverage of all possible module activation paths, the RegisteringInstance event is wired up.

    Conclusion

    While you still have to create your own view to display the module information, this service should provide you with the required information to display module status information and make the task of retrieving module status information a whole lot easier.

    The extension can be found on CodePlex in the sourcecontrol of CompositeWPFContrib

More Posts Next page »
Powered by Community Server, by Telligent Systems