What Progression Providers?
I mean those commands in the Architecture Explorer. For example the “Insert into Active Diagram” command which generates a sequence diagram from the selected method or the “Save as XPS…”.
And just because Visual Studio is extensible from top to bottom it should be easy to make your own commands.
Why would you want to create your own Progression provider? For example, you could make your own “Import from strange format…” or “Export Model to strange format…” commands, XMI for example. I want a command “Generate TestCase…” for this solution Rosario Video - Generate TestCases from ActivityDiagram and I also thinking of changing GAX/GAT actions in progression commands, will save me some installation problems... many possibilities for the progression commands to get useful. Although the user-interface good have some usability improvements.
The providers can be found in the “C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\Providers\” folder and are loaded on runtime. No configuration and no installation is required. Just put your provider-assembly in this directory and the commands will appear in the Architecture Explorer.
This can solve an interesting problem when you work within different teams.
The problem with different teams and extensibility is that Visual Studio extensibility is “developer”machine focused and not project focused. For example, when you want to use an GAT package within a projectteam all of the team-members must install that package. A new team member must start his first day by installing and configuring the packages/ customizations used by that project. When you work on many different projects where each project has his own set of customizations this can be awkward, you have to maintain as many different environments as projects. With the Progression providers “assembly only” approach it will get much easier, just copy past the assemblies or when it’s possible to put them in the same directory as your project [didn’t tried this, maybe some kind of reg-key or config setting which points to the providers]. We could put them in source control [nice wane have] just a get latest will setup your development environment. That will even solve the visioning problem… nice!
There are already five providers in the “…\PrivateAssemblies\Providers\” folder, let’s examine them with Reflector . A quick look in to the Progression namespace together with the providers tells [see image] that all of them use the Microsoft.VisualStudio.Progression.Common and .Interfaces.
What are the most important classes used by the providers… In Dependency Matrix 2 [below] you can see that the ProviderAttribute and the Transalator is used by all of them and StateMachine classes by 3 out 5. So that are the interesting classes to look at.
The same way you can see that classes prefixed with provider most heavily use [depend on] the ProviderAtrtribute, Translator and StateMachine classes from Microsoft.VisualStudio.Progression.Common.
So, now we know where to look let’s see what these classes do [NDepend right mouse click go to Reflector]. First the DSLProvider, and as expected there is a Provider attribute and an inheritance from Translator. The Translator class has some WPF methods DependencyProperties and some abstractmethods we need to implement.
The Translator method Added runs immediately when the Architecture Explorer starts and the method BecomeActive is called by some kind of interval [still don’t know where it is triggered]. The Tick method is fired by System.Windows.Threading.DispatcherTimer.FireTick and the other methods have logical names.
The only class left to analyse is the StateMachine class and it does exactly what the name say’s. It’s a statemachine, with a little bit of knowledge of the State Pattern is this class easy to understand [you can find in this issie of the MSDN magazine some background, this article “Design Patterns: Solidify Your C# Application Architecture with Design Patterns”].
A state has an enter, exit and update delegate. So, these are methods which are executed at the moment of state change. A statemachine can have different states, you create them with the CreateState method. this method saves the different states in a Dictionary. for example when Enter on the statemachine is processed it fires the StateEnter delegate. You also can add events which helps by the transition between states.
Enough analysing… let’s make our own Progression Provider.
- Start a new Class Library project.
- Add the Provider attribute and the Translator, IDisposable inheritance.
- Add a constructor where we initialise a new statemachine, create states and events.
This piece of code, initialise a new statemachine, create two states which both have only a StateUpdate delegate. [I have to play with these different kind of delegates, still don’t know what’s the best way…]. The two events both put the statemachine in idle state.
- Implement the added method, we register the action/command so it will be visible in the Architecture Explorer and put the statemachine in Idle state.[You can really do a lot with the RegisterAction method, I think this is the most minimal way to use it]
- BecomeActive is checked constantly with some kind of interval and I had some challenges with this. What resulted in an empty Architecture Explorer and many errors. Anyway, when everything works it enters the ActionHandling state. That one looks in the pendingactions dictionary for the command he wants to execute, mine is called 0xbb6.
After this complete the rest of the methods and do what ever you want…
- Finally, copy past the created assembly to the “…\PrivateAssemblies\Providers\” directory start Visual Studio and have fun with YourFirstProgressionCommand…
This one really does magic… it say’s something like “Hello….” in a windowsform.
Some final words…
This is really a “Hello World” implementation of a progression command, there are many area’s for investigation left… but, it works and I think there will follow many more commands.