Monday, February 16, 2015

Self-disciplined Agile Monitoring

Note for readers: I wrote this post over a year ago (even more), but for some reason I forgot to post it, so here it is.

Introduction

Now days, we are improving our development process laying-out our organization strategies, development process and methodologies. 

Our experiences point to a mixed approach, with the self-organization from Scrum and self-discipline from eXtreme Programming (XP). But about this kind of “mixed martial arts” for software development approach I will talk in forthcoming blog post. 

As you can read in one of my previous blog post, we use Team Foundation Server (TFS) as issue tracker and thanks to Scrum for Team System v3 (STSv3) process template, we have an “excellent” implemented guidance to execute Scrum “as is”.

But the existing day by day sprint monitoring’s tools around this process template hides the real behavior of the team in the iteration. 

On the other hand, we also have some needs about monitoring. Indeed against the theoretical practice of monitor the whole team we have to track individuals.

Some projects leads (me included) want to track theirs developers work against the importance of monitor the whole team behavior. Sam Guckenheimer (with Juan J. Perez), in his book “Software Engineering with Microsoft Visual Studio Team System”, aims us to use descriptive metrics rather than prescriptive. But here such measurement method “doesn’t work”, we need more control and also need a single view. 

Tracking the daily work in STSv3

Scrum for Team System (v3) is a great process template. Its major advantage of this implementation for TFS is about the usage of the server side event notification API. This allows updating all of computable fields for instance: start and end time for sprints (summarized from team start and end sprint dates), remaining hours for sprints and team sprints, and so on.

Scrum for Team System also comes with a lot of reports, but about daily work sprint monitoring comes with only one (maybe two).  This report is known as Sprint Burn Down

The burn down metric

The Sprint Burn Down is good metric but it’s incomplete. Such single line indeed hides the real behavior of iteration. 

Please, try to answer these questions:
  • How can you notice if some tasks where moved out of the current sprint?
  • How can you notice if some user stories where moved out of the current sprint?
  • How can you notice if some tasks where added to the current sprint?
  • How can you notice if some user stories where added to the current sprint?
The fact is that as this chart doesn’t display the planned work so it hides these behaviors. 

Notice:
  1. If you see an ideal chart, an straight down line from an amount of hours as remaining work (at some point of the sprint) to zero (at the end of the sprint), doesn’t mean that everything is fine. May some tasks were moved of the sprint.
  2. If you see a horizontal line doesn’t mean that everything is wrong. May some tasks were added at the same time that others were actually done. 
The burn down metric

The fact is that you are not able to answer this question: What had really happened here?

Complementary tools to track the daily work

One of my favorites tools to track iterations, and also share the iteration status with the whole team is ScrumSprintMonitor. Yes, the multi-process template screen saver. 

The effect of the usage of this tool in the team’s focus is incredible and of course, more over the “guys in red” ;-).
Demo screenshot of ScrumSprintMonitor from codeplex and ScrumSprintMonitor in action but in planning mode in a lab
I like the Scrum Sprint Monitor and have been using it for years, even when I had no longer available the TV in the picture above. But again, the main metric is the Burn Down.

This tool includes a lot of info so I get inspired and wrote my own, just like I thought that it should be written ;-).

Self disciplined agile monitoring

Well, the thing actually started some years ago when I found this chart in the book “The Art of Agile Programming” from James Shore and Shane Warden. Its name is Burn Up. 

Basically consist of a couple of lines. One to show the total of planned work and the second to display the progress.

The burn up metric

In the context of a project to help my own organization to get the right way in terms of software development practices, I bought some time in order to port this metric into this monitoring application.

My own ScrumSprintMonitor in action with the burn up metric
As I said before it was inspired in Scrum Sprint Monitor but it was re-written from scratch to focus in the Burn Up metric. The current version it’s only compatible with STSv3.

Conclusion

  1. Now we have a very cool monitoring application with a very meaningful metric. The Burn Up. 
  2. In order to distribute as fast as possible this tool and its updates across my organization, I also implemented a draft of NuGet based automatic update system. After done, someone told me about something called Shimmer. I have to review it ;-).
  3. I almost forget. This application is powered by Catel and Prism in combination (a.k.a. Catel.Extensions.Prism). 
Happy sprinting and monitoring ;-)

Monday, January 19, 2015

Why you should start using NDepend?

Introduction

This weekend I finished painting my apartment. Then I laid on the floor, looking at the ceiling, started taking some shoots and talking to myself:

A) Yes, it looks great and with this new lamp in the middle of the living room, everything looks perfect. B) But what is that I see at the corner? Let me get a closer shoot. C) Oops!!! I made a mistake, I need to fix it ASAP ;)

Yes, I know, I’m not a professional painter. Therefore, I don't have the right tools to alert me about this technical debts while I’m painting. 

Such experience reminded me that I’m a software developer and recently acquired the right tool detect such “dark spots” – a.k.a technical debt – of the source code while I’m coding. Its name is NDepend.

What is NDepend?

SONAR Web Report
NDepend is a static analysis tool for .NET managed code. As you should know static analysis is about analyzing code without execute it and generally used to ensure conformance with the coding guidelines.

NDepend is not the only tool available for static analysis code for .NET, there are several tools including Code Violation Detection Tools like Fxcop, Clocksharp, Mono.Gendarme or CodeIt.Right,  Quality Metric Tools like Nitriq, SONAR or NDepend itself, or just Checking Style Tools like StyleCop, Agent Smith.

Actually, I currently use SONAR with its seamless integration with build process in order to continuously manage code quality in centralized reports of technical debts.

NDepend also have integration with the build process, but from my point of view one of its key feature is the great Visual Studio integration in order to display your technical debt directly inside the IDE.
NDepend Dashboard in Visual Studio
Lets take a look into a very quick start with NDepend.

A very quick start with NDepend


Quick access
to the violation results
After install a plugin and setting up your  project, you should run a code analysis just by clicking the option from the menu NDEPEND => Analyze => Run Analysis or moving de mouse over a circle in the notification bar and click in run a First Analysis on this NDepend Project.

If you move the mouse again - once the analysis finished - over the circle in the notification bar you should see the Code Queries and Rules Summary, with the fast access to the Critical and Rules Violated

Such results, categorized into Code Quality, Object Oriented Design, Design, ArchitectureLayering, Dead Code, and so on, are displayed into the Query and Rules Explorer panel and allow us to navigate from the violation directly into the source.
Categorized violation query results on the Query and Rules Explorer
For instance let me check from Code Quality category, the rule Methods with too many parameters - critical.  

The rule description is the follow: Methods with more than 8 parameters might be painful to call and might degrade performance. You should prefer using additional properties/fields to the declaring type to handle numerous states. Another alternative is to provide a class or structure dedicated to handle arguments passing.

The analysis found 16 violations about this rule, by clicking it you can navigate to the method. In this case, I selected one with 9 parameters and found out that indeed, it must be refactored. Now, thanks of the integration of Visual Studio and Git,  you can also see who's the author of this violation. 

Navigating from rule 'Methods with too many parameters - critical' result to StartSiteCreationProcess method
Let me take a closer shoot to see who that is:

Oops!!! it's me, I need to fix this ASAP ;)

Conclusion

Important thing is, not to accumulate technical debt and fix it as soon as it is detected. For .NET developers, NDepend is the right tool to start with.

You can make mistakes (critical or not), but be aware about your code quality constantly makes the difference between the apparent and intrinsic quality of your sources and consequently your products; even when untrained eyes may only see the beautiful lamp.

Btw, It seems like I've got similar skills as painter than as software developer ;).

Tuesday, September 23, 2014

How setup SharePoint web application to write SignalR based application pages?

There are few steps to enable SignalR into a web application. But how do this for a SharePoint based web application? 

The goal of this post is provide you a SharePoint deployment package to is automate such steps for a SharePoint web application.

The only thing you have to do is:

2) Install the SignalR distributed assemblies the web application bin directory from Powershell console:

>Add-PSSnapin Microsoft.SharePoint.PowerShell
>Add-SPSolution (Resolve-Path .\SignalR.SharePoint.wsp)
>Install-SPSolution SignalR.SharePoint.wsp -WebApplication $WebAppUrl -GACDeployment -FullTrustBinDeployment -Force

3) Enable [SignalR SharePoint Configuration Feature] - in the web application scope - in order to modify the web.config for run-time assembly binding redirection, set legacyCasModel to false (allow dynamic calls) and set the owin:AutomaticAppStartup application setting key to false.

...
   <trust level="Full" originUrl="" legacyCasModel="false" />
...
  <runtime>
    <assemblyBinding>
...
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
...
  <appSettings>
...
    <add key="owin:AutomaticAppStartup" value="false" />
  </appSettings>

4) Create and deploy your hub based assembly into the web application. The easy way to do this is by writing the hub in a SharePoint based project and set the “Assembly Deployment Target” to WebApplication. You can also try with this simple chat example by deploying it into your web application.

5) Enable the [SignalR SharePoint Enable AutomaticAppStartup Feature] - in the web application scope - in order turn the owin:AutomaticAppStartup application setting key to true.

  <appSettings>
...
    <add key="owin:AutomaticAppStartup" value="true" />
  </appSettings>

6) Just open your browser and navigates to the application page. If you deployed the chat example, you can try with %WebApplicationUrl%/_layouts/15/_layouts/15/SignalR.SharePoint.Demo/Chat.aspx application page.

Monday, August 11, 2014

What about Catel.Fody and computed read-only properties change notifications?


On my last post I covered an implementation of INotifyPropertyChanged interface when using SheepAspect as AOP library. At the end, I also implemented an approach to notify changes of computed read-only properties. This approach has a down side, the dependent properties discovering process must be done in run-time.

Such journey recall us that Catel.Fody didn’t have support for notify property changes of computed read-only properties. How could such thing ever be possible? Obvious, “the shoemaker's son always goes barefoot” ;). But don’t worry: the feature is here, moving the dependent properties discovering process to build-time, thanks to Fody.

As you probably know by now, Catel.Fody will rewrite all properties on the DataObjectBase and ViewModelBase. So, if a property is written as this:

public string FirstName { get; set; }

will be weaved into

public string FirstName
{
    get { return GetValue<string>(FirstNameProperty); }
    set { SetValue(FirstNameProperty, value); }
}

public static readonly PropertyData FirstNameProperty = RegisterProperty("FirstName", typeof(string));


But now we added a new feature to Catel.Fody. If a read-only computed property like this one exists:

public string FullName
{
    get { return string.Format("{0} {1}", FirstName, LastName).Trim(); }
}

the OnPropertyChanged method will be also weaved into

protected override void OnPropertyChanged(AdvancedPropertyChangedEventArgs e)
{
    base.OnPropertyChanged(e);
    if (e.PropertyName.Equals("FirstName"))
    {
        base.RaisePropertyChanged("FullName");
    }
    if (e.PropertyName.Equals("LastName"))
    {
        base.RaisePropertyChanged("FullName");
    }
}


This feature is already available in the latest beta package of Catel.Fody.

Try yourself and let us know.

Monday, June 30, 2014

Implementing notify property changed with SheepAspect

Introduction

I spend some time looking for AOP options for .NET.  All references point to PostSharp the coolest option - even when you have to pay for use it - due by its features, starting from the way it works – in build time and static – plus the lot of build-in “advices” and extensions points.

There are also several run time and dynamic options such as Castle, Unity, etc., but I prefer the build time and static approach.  Indeed I use Fody - as alternative to PostSharp - even when I have to write down custom plugins directly in IL.

But all of these AOP like libraries and tools for .NET do not allow you handle exactly the all the AOP concepts such as pointcut, join-point and advice.

But recently I found a project in codeplex, named SheepAspect with an introduction statement that include the following words “…was inspired in AspectJ”. So, I just installed the package from NuGet and started to write in C# a notify property changed proof of concept with a friend of mine (Leandro).

Introducing NotifyPropertyChanged aspect

The very first step is write a NotifyPropertyChangedAspect class. It’s important get related with SAQL in order to query the right properties from the right types, and with the SheepAspect attributes usage. For this particular example the pointcut includes “all public property setters of types that implements System.ComponentModel.INotifyPropertyChanged” and look like this:
[Aspect]
public class NotifyPropertyChangedAspect
{
    [SelectTypes("ImplementsType:'System.ComponentModel.INotifyPropertyChanged'")]
    public void NotifiedPropertyChangedTypes()
    {
    }

    [SelectPropertyMethods("Public & Setter & InType:AssignableToType:@NotifiedPropertyChangedTypes")]
    public void PublicPropertiesOfTypesThatImplementsINotifyPropertyChangedInterfacePointCut()
    {
    }
}

Now, I just needed to add the notify property changed behavior as around advice just as follow:

[Around("PublicPropertiesOfTypesThatImplementsINotifyPropertyChangedInterfacePointCut")]
public void AdviceForPublicPropertiesOfTypesThatImplementsINotifyPropertyChangedInterface(PropertySetJointPoint jp)
{
    object value = jp.Property.GetValue(jp.This);
    if (!object.Equals(value, jp.Value))
    {
        jp.Proceed();
        jp.This.RaiseNotifyPropertyChanged(jp.Property);
    }
}

As you should notice, to implement this, I also introduce a couple of extension methods TryGetPropertyChangedField and of course the RaiseNotifyPropertyChanged itself:

public static bool TryGetPropertyChangedField(this Type type, out FieldInfo propertyChangedEvent)
{
    propertyChangedEvent = null;
    while (propertyChangedEvent == null && type != null && type != typeof(object))
    {
        propertyChangedEvent = type.GetField("PropertyChanged", BindingFlags.Instance | BindingFlags.NonPublic);
        if (propertyChangedEvent == null)
        {
            type = type.BaseType;
        }
        else if (!typeof(MulticastDelegate).IsAssignableFrom(propertyChangedEvent.FieldType))
        {
            propertyChangedEvent = null;
        }
    }

    return propertyChangedEvent != null;
}

/*...*/

public static void RaiseNotifyPropertyChanged(this object instance, PropertyInfo property)
{
    FieldInfo propertyChangedEvent;
    if (instance.GetType().TryGetPropertyChangedField(out propertyChangedEvent))
    {
        var propertyChangedEventMulticastDelegate = (MulticastDelegate)propertyChangedEvent.GetValue(instance);
        var invocationList = propertyChangedEventMulticastDelegate.GetInvocationList();
                
        foreach (var handler in invocationList)
        {
            MethodInfo methodInfo = handler.GetMethodInfo();
            methodInfo.Invoke(handler.Target, new[] { instance, new PropertyChangedEventArgs(property.Name) });
        }
    } 
}

Now, if a class that implements or inherits from a class that implements INotifyPropertyChanged interface is added, just like this one:

public class Person : INotifyPropertyChanged
{
        public event PropertyChangedEventHandler PropertyChanged;

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string FullName
        {
            get
            {
                return string.Format(CultureInfo.InvariantCulture, "{0} {1}", this.FirstName, this.LastName).Trim();
            }
        }
}

and a program like this one is written:

this.person.PropertyChanged += (sender, args) =>
                {
                    object value = sender.GetType().GetProperty(args.PropertyName).GetValue(sender);
                    Console.WriteLine("Property Changed => '{0}' = '{1}'", args.PropertyName, value);
                };

this.person.FirstName = "Igr Alexánder";
this.person.LastName = "Fernández Saúco";

then the output will be:

Property Changed => 'FirstName' = 'Igr Alexánder'
Property Changed => 'LastName' = 'Fernández Saúco'

Uhmm! But what about with the computed read-only properties like FullName?

Notifying property changes of computed readonly properties.

In order to notify changes of computed read-only properties an inspection of the IL code is required. The .NET native reflection API is limited. From the PropertyInfo is only possible get the IL byte array from of the get method body, and nothing more. Therefore, I just switched to the Mono.Cecil reflection API to be able to complement the existing RaiseNotifyPropertyChanged extension method with the following extension methods:

public static bool ExistPropertyDependencyBetween(this Type type, PropertyInfo dependentProperty, PropertyInfo propertyInfo)
{
    AssemblyDefinition assemblyDefinition = new DefaultAssemblyResolver().Resolve(type.Assembly.FullName);
    TypeDefinition typeDefinition = assemblyDefinition.MainModule.GetType(type.FullName);
    PropertyDefinition dependentPropertyDefinition = typeDefinition.Properties.FirstOrDefault(definition => definition.Name == dependentProperty.Name);
    
    bool found = false;
    if (dependentPropertyDefinition != null)
    {
        MethodDefinition definition = dependentPropertyDefinition.GetMethod;
        if (definition.HasBody)
        {
            ILProcessor processor = definition.Body.GetILProcessor();

            int idx = 0;
            while (!found && idx < processor.Body.Instructions.Count)
            {
                Instruction instruction = processor.Body.Instructions[idx];
                
                MethodDefinition methodDefinition;
                if (instruction.OpCode == OpCodes.Call && (methodDefinition = instruction.Operand as MethodDefinition) != null && methodDefinition.DeclaringType.IsAssignableFrom(typeDefinition) && methodDefinition.Name == string.Format(CultureInfo.InvariantCulture, "get_{0}", propertyInfo.Name))
                {
                    found = true;
                }
                else
                {
                    idx++;
                }
            }
        }
    }

    return found;
}

/*...*/

public static IEnumerable<PropertyInfo> GetDependentPropertiesFrom(this Type type, PropertyInfo property)
{
    List<PropertyInfo> dependentPropertyInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(dependentProperty => property != dependentProperty && dependentProperty.CanRead && type.ExistPropertyDependencyBetween(dependentProperty, property)).ToList();
    for (int i = 0; i < dependentPropertyInfos.Count; i++)
    {
        foreach (PropertyInfo info in type.GetDependentPropertiesFrom(dependentPropertyInfos[i]))
        {
            if (!dependentPropertyInfos.Contains(info))
            {
                dependentPropertyInfos.Add(info);
            }
        }
    }

    return dependentPropertyInfos;
}
just like this:
public static void RaiseNotifyPropertyChanged(this object instance, PropertyInfo property)
{
    FieldInfo propertyChangedEvent;
    if (instance.GetType().TryGetPropertyChangedField(out propertyChangedEvent))
    {
        var propertyChangedEventMulticastDelegate = (MulticastDelegate)propertyChangedEvent.GetValue(@this);
        var invocationList = propertyChangedEventMulticastDelegate.GetInvocationList();
                
        foreach (var handler in invocationList)
        {
            MethodInfo methodInfo = handler.GetMethodInfo();
            methodInfo.Invoke(handler.Target, new[] { instance, new PropertyChangedEventArgs(property.Name) });
        }

        foreach (PropertyInfo propertyInfo in instance.GetType().GetDependentPropertiesFrom(property))
        {
            foreach (var handler in invocationList)
            {
                MethodInfo methodInfo = handler.GetMethodInfo();
                methodInfo.Invoke(handler.Target, new[] { instance, new PropertyChangedEventArgs(propertyInfo.Name) });
            }
        }
    }
}

So, now the program output is:

Property Changed => 'FirstName' = 'Igr Alexánder'
Property Changed => 'FullName' = ' Igr Alexánder' 
Property Changed => 'LastName' = 'Fernández Saúco'
Property Changed => 'FullName' = ' Igr Alexánder Fernández Saúco'

Conclusion

At this point you should be worry about the performance and the lot of reflection API calls. I'm pretty sure that this issue could be handle with a right caching approach ;).

I didn’t know why I never heard about SheepAspect before. Probably no one trust in something called “Sheep”, but believe me SheepAspect rocks!

Wait a second! Right now I'm reading about something called mixing. Probably I can get a more declarative approach to implement this, just like the Fody or PostSharp home page examples. But I'm not sure right now, so, you have to wait for my next post to know about it ;).

Friday, February 21, 2014

Developing a ReSharper Plugin – The backward compatibility approach

Introduction

We have being developed a ReSharper plugin for Catel framework also known as CatelR# for a while, following an interesting approach in order support the new R# version and also keep the backward compatibility.

If you want to know how we made it, just take a look.

Visual Studio solution setup

1)    Create project per supported R# version, which means that the output of each project is targeting to the specific version of R# and references the specific version of the SDK.



2)    Keep in mind, that could be several breaking changes between R# SDK versions, but nothing that couldn’t be handled with pre-processor directives.

#if R70 || R71 || R80
        protected override void Process(CSharpGeneratorContext context)

#elif R61
        public override void Process(CSharpGeneratorContext context)
#endif
        {
            CSharpElementFactory factory = CSharpElementFactory.GetInstance(context.Root.GetPsiModule());
#if R80
            IDeclaredType viewModelToModelAttributeClrType = TypeFactory.CreateTypeByCLRName(CatelMVVM.ViewModelToModelAttribute, context.PsiModule, UniversalModuleReferenceContext.Instance);
#else
            IDeclaredType viewModelToModelAttributeClrType = TypeFactory.CreateTypeByCLRName(CatelMVVM.ViewModelToModelAttribute, context.PsiModule);
#endif
            /*...*/
#if R80
                        var fixedArguments = new List<AttributeValue> { new AttributeValue(ClrConstantValueFactory.CreateStringValue(model.ShortName, context.PsiModule, UniversalModuleReferenceContext.Instance)) };
#else
                        var fixedArguments = new List<AttributeValue> { new AttributeValue(ClrConstantValueFactory.CreateStringValue(model.ShortName, context.PsiModule)) };
#endif
                        if (propertyName != modelProperty.ShortName)
                        {
#if R80
                            fixedArguments.Add(new AttributeValue(ClrConstantValueFactory.CreateStringValue(modelProperty.ShortName, context.PsiModule,  UniversalModuleReferenceContext.Instance)));
#else
                            fixedArguments.Add(new AttributeValue(ClrConstantValueFactory.CreateStringValue(modelProperty.ShortName, context.PsiModule)));
#endif
                        }
            /*...*/
                    }
                }
            }
        }

3)    Keep all these entire project sources synchronized. Could be very easy thanks to Caitlyn.




4)   Finally redirect the build projects outputs to dealing with ease with the packaging of the deployment units.

Building the deployment units

The R# plugin build process indeed an heterogeneous one as any build process. Even though  this build could be handled via msbuild tasks, we actually recommend the usage of tools with intuitive GUI in order to quickly creating and debugging such build "scripts", such as FinalBuilder or VisualBuild.


1) Since 8.0 R# version  the NuGet based extension manager is available. Therefore one of the build output could be a NuGet package to distribute your plugin through the ReSharper extension gallery.

2) But NuGet based extension manager is not available for all R# versions. Therefore a second build output could also be classic deployment unit built on top of any of the existing installer system.  For instance InnoSetup or NSIS.

The following are the code snippets from the install and uninstall sections of CatelR# setup. Notice how we deal with build output to support all R#  versions.


# ...
# Installer section
# ...

Push "v6.1"
Push "v7.0"
Push "v7.1"
Push "v8.0"
Push "v8.1"
${Do}
  Pop $0
  ReadRegStr $1 HKLM "Software\JetBrains\ReSharper\$0" InstallDir
  ${If} $1 != ''
    DetailPrint "Installing Catel.ReSharper for JetBrains ReSharper $0"
    SetOutPath "$1\Plugins\$(^Name)"
    ${If} $0 == 'v6.1'
      File /r "..\..\output\Debug\v6.1\*.dll"
    ${ElseIf} $0 == 'v7.0'
      File /r "..\..\output\Debug\v7.0\*.dll"
    ${ElseIf} $0 == 'v7.1'
      File /r "..\..\output\Debug\v7.1\*.dll"
    ${ElseIf} $0 == 'v8.0'
      File /r "..\..\output\Debug\v8.0\*.dll"
    ${ElseIf} $0 == 'v8.1'
      File /r "..\..\output\Debug\v8.1\*.dll"
    ${EndIf}
    Push true
    Pop $3
    WriteRegStr HKLM "${REGKEY}" "$0" 1
  ${EndIf}
${LoopUntil} $0 == "v6.1"

# ... 

# ... 
# Uninstaller section
# ... 

Push "v6.1"
Push "v7.0"
Push "v7.1"
Push "v8.0"
Push "v8.1"
${Do}
  Pop $0
  ReadRegStr $1 HKLM "${REGKEY}" "$0"
  ${If} $1 == '1'
    ReadRegStr $2 HKLM "Software\JetBrains\ReSharper\$0" InstallDir
    ${If} $2 != ''
      RMDir /r /REBOOTOK "$2\Plugins\$(^Name)" 
      DeleteRegValue HKLM "${REGKEY}" "$0"
    ${EndIf}
  ${EndIf}
${LoopUntil} $0 == "v6.1"  

# ...


Conclusions

Just a few minutes ago, I read the notification about the release of R#8.2 EAP. It’s a good moment to revalidate this approach. Let’s see,… creating a new project with post-fix 82, …installing the SDK package, ..., ...time out, sorry…slow connection…,…,…,..updating the build script, …, …, … reviewing for breaking changes, good news, there are no breaking changes,… updating setup script…., committing source modifications, … running the build script and it’s done.

Now you can update the extension from the extension gallery or download the full installer of CatelR# with support for R#8.2 EAP ;)

Tuesday, October 22, 2013

Catel extends Prism modularity options through NuGet

Introduction


Prism provides a lot of options regarding modularity by default. Fact is that most of the stuff  you need to build a modularized application is available on Prism. Prism contains several modularity options including ways to retrieve modules from a directory, set them up through the configuration file, and even options to create modularized Silverlight applications.

On the other hand, Catel provides support for module catalog composition in order to enable more than one modularity options into a single application.

Nowadays, initiatives around NuGet come from everywhere, such as Shimmer with the same goal of ClickOnce (but works), OctopusDeploy for release promotion and application deployment or even the recently released extension manager of ReSharper 8.0.

So, the Catel team comes with a new one and the fact is that we wondered why no one told about this before: 

What if you would be able to distribute your application's modules through NuGet?

If you want to know how, take a look.


Enabling NuGet based modularity option


With the forthcoming 3.8 version of Catel you will be able to install and load modules from a NuGet repository. The only thing you have to do is:
  1. Write a module as you know with Prism (or better in combination with Catel).
  2. Create a NuGet package for the module and publish it into your favorite gallery.
  3. Use and configure the NuGetBasedModuleCatalog in the application’s bootstrapper.
The first two steps are well documented. For details see creating and publishing a package and declaring modules from NuGet and Catel documentation.


So, now we can focus on the third one.

Use and configure the NuGetBasedModuleCatalog in the application’s bootstrapper


In order to simplify the following explanation we published a package into the official NuGet Gallery named Catel.Examples.WPF.Prism.Modules.NuGetBasedModuleA. Such package contains an assembly with a single class like this one:
 
public class NuGetBasedModuleA : ModuleBase
{
    public NuGetBasedModuleA(IServiceLocator container):base("NuGetBasedModuleA", null, container)
    {
    }

    protected virtual void OnInitialized()
    {
      var messageService = this.Container.ResolveType<IMessageService>();
      messageService.Show("NuGetBasedModuleA Loaded!!");
    }
}

Let’s start writing an  application that will use this public packaged module. Indeed, the main point of interest here is about the usage and configuration of the NuGetBasedModuleCatalog. Therefore just write the bootstrapper as follow:

public class Boot : BootstrapperBase<MainWindow, NuGetBaseModuleCatalog>
{
  protected override void ConfigureModuleCatalog()
  {
    base.ConfigureModuleCatalog();
    this.ModuleCatalog.AddModule(new ModuleInfo 
          { 
               ModuleName = "NuGetBasedModuleA", 
               ModuleType = "Catel.Examples.WPF.Prism.Modules.NuGetBasedModuleA.NuGetBasedModuleA, Catel.Examples.WPF.Prism.Modules.NuGetBasedModuleA", 
               Ref = "Catel.Examples.WPF.Prism.Modules.NuGetBasedModuleA, 1.0.0-BETA", 
               InitializationMode = InitializationMode.OnDemand
          });
  }
}

Notice how the Ref property of ModuleInfo is used to specify the package id and optionally the version number. If the version number is not specified then the application always will try to download the latest version keeping the modules up to date.

Finally, to make this demo work, just put in the XAML of the main window the ModuleManagerView control, run


and click the check box.

Conclusions


Yes, we did it again. Catel keeps working alongside Prism. Now, we extended Prism’s modularity options through NuGet in order to provide a powerful mechanism of application module distribution. 

If you want to try, just get the latest beta package of Catel.Extensions.Prism and discover by yourself all scenarios that you can handle with this Catel exclusive feature.