Wednesday, December 16, 2009

DXCore Docs

People keep asking me where to start when learning to build plugins… specifically they ask me where the documentation is..

At this point I’m typically at a loss, because the docs (such as they are at this point) exist as collection of disparate articles, posts and references across a few locations:

So in an effort to centralize some answers to some of the more common DXCore related questions, I'm starting to put together some task based documentation at http://sites.google.com/site/dxcoredocs/

It is not intended that this will turn into an API reference ... That will ultimately be down
to DX.

However I'm being asked certain task based questions often enough, that it's
becoming worth my while to create some prebuilt answers of my own that I can point people at… and my blog isn’t the easiest place to browse through :)

Initially some of the content will redirect to relevant articles on my blog or posts in the Forums but with luck I will eventually find time to rewrite some of this content direct in DXCore Docs.

At the very least, new content will be presented via DXCore Docs in an effort to make it easier to browse and digest.

Also note that similar CodeRush based information is available at a similar site:http://sites.google.com/site/coderushdocs


Wednesday, November 04, 2009

CodeRush Scenarios


This is a simple post to point out some scenarios in which a tool like CodeRush can be invaluable.

Refactoring

Bashing out a quick algorithm.

I have no fear. I can hack out a working solution pretty quickly when I’m called upon to do so, but when done this way, it’s typically not very pretty. However, with a few keystrokes I can extract component parts of my ‘rough and ready’ algorithm to other methods, allowing me to sensibly reuse code which I might otherwise have copied and pasted and then had to maintain independently.

Tidy that Code.

The code I wrote last year is ugly. Hell, the code I wrote last week is ugly, when compared with what I wrote yesterday or today. All code can stand to be improved, but it’s rare that you want to go back and actually improve it because that code you wrote yesterday, is yesterday’s news. You don’t want to have to reconsider your old code because its time consuming and boring. Well some simple Refactorings, like ‘Rename’, ‘Extract Local’ and ‘Inline Temp’, really do help speed the process to the point where you can feel your code quality rising by the second, which can really enthuse you to do more.

Spreken zie code?

Ok… I don’t really speak any foreign languages but I do know what it’s like to have to interpret a foreign codebase. It’s hard. you rarely have the ear of someone whose uses the code, much less the moron who created it in the first place. With CodeRush, I can glide around the codebase renaming types, methods and variables as I see fit… Morphing the codebase ever closer to that illusive “Readable code”. I can do this completely safe in the knowledge that I am not altering the way the code works, just the way it reads.

Efficient Code Review.

Code-Reviews can take up a lot of time. The important part, is not tidying up the code, but imparting knowledge of why the suggestions are real improvements. You want to spend as much of your time “teaching the man to fish” rather than “throwing fish in the his general direction hoping he’ll catch one”. After all… if you “teach a man to code *well*” you wont have to “code well for him”. CodeRush helps you spend less of your time improving or correcting the code being reviewed, so that you can spend more of your time either explaining why the improvements are so good or simply get on with improving more code. Also, using CodeRush (even the Xpress version) has an added benefit that in addition to demonstrating good code, you are demonstrating the use of good coding tools.

CodeProviders

API-By-Example.

API-By-Example (also known as consume-first development) is a process where in you call a non-existent method… in a way you imagine that you would like to be able to call it… passing parameters in a way you see as sensible to do … and using any return value it produced in a way you see as reasonable… all without ever having actually coded the signature, or indeed any of the implementation, of the method in question. It’s like a big ol’ game of ‘Let’s pretend’. except that when you’re finished doing all of that, you get to hit a single key and generate this method’s signature exactly according to it’s usage.

You have just designed your first API-By-Example. Once generated, the method’s own signature can be used a partial spec against which a implementation can be built, safe in the knowledge that the call already makes sense in situé.

This sort of technique is great for creating library or framework code because you first define how you'd like to use it and then move on from there to the implementation. You arrive at a library which is much more usable because it was designed with it's usage in mind from the outset.

The CodeRush SmartTag
The CodeRush SmartTag contains both Refactorings and CodeProviders specific to the context in which you find yourself.

My personal favourites are:

  • Refactorings
    • Rename
    • Extract Local
    • Extract Method
    • Extract Property
    • Inline Temp
  • Code Providers
    • Declare Local
    • Declare Method (With parameters all in place based on your usage.)
    • Declare Property
    • Declare Field With Initializer

..but there are many more. :)

Which ones do you use most and in what situations ?

-------------------------------------------------------------------------------------------
For more details on CodeRush and other DevExpress products, check out their Facebook page
-------------------------------------------------------------------------------------------


Wednesday, August 26, 2009

CodeRush … Take some Time to Tune.


So you’ve just been handed a copy of CodeRush and told that it’s the future.. Whomever told you this, is very insightful and deserves much of your respect :D

After installing, the first thing you should do, is to give CodeRush an idea of how you like things done. I have decided to compile this little list of the options that I change and why, in the hopes that this will help ease you into working with your new best friend.

So options… where are they then?

Access to the options screen is granted via the options entry on the DevExpress menu.

If you see no DevExpress menu, then you either don’t have CodeRush installed, or you are running the Xpress version (I think MS asked that it not have the DevExpress menu)

If this is the case, you have 2 options…

  • Suck it up and hit Ctrl+Shift+Alt+O and your options should appear.
  • Bust out RegEdit and go to town on your registry. (Note that the latest version is 9.2 not 9.1)

Ok so now you’re into the options screen. Each page (on the left in the tree) is created and dynamically added to this tree by the plugin that it represents. This means that as a plugin developer I can seamlessly add pages to this tree for my own plugin.

Additionally some of the options pages are considered Advanced or Expert rather than the default of New User. see the little Level dropdown in the bottom left of this screen to alter your current setting. Further, some pages are language specific, so you’ll need to set the Language dropdown (a little to the right of the level dropdown) to the language you’re looking to configure.

So what settings do I alter?

Code Style (Editing\Code Style\Identifiers)

There are a few pages under Editing\Code Style which you should definitely browse through. I generally find the default to be more than satisfactory. However my own personal preferences differ slightly on the Identifiers page. I prefer Pascal Case for everything, but will prefix fields with an ‘m’ (for module level). This is purely a readability issue.

Organization(Editor\Organization\Member Mover)

This relates to the “Move to Region” function under the little icon to the left of each of your method signatures. If clicked, it presents you with a list of regions into which you might wish to move the method in question.

This list contains regions that already exist with the current code file. The options page allows you to preconfigure an additional list of regions which will appear in this menu, regardless of whether or not they already exist in the code file.

I tend to configure the following regions (each on a separate line)

Fields

Simple Properties
Constructors
UI Events

Extraction and Generation

There are several places in the options where CodeRush gives you the option to specify the location where generated code will appear, relative to your current position. I don’t like having to tell CodeRush where to place generated items each and every time. I’d far rather set up a default.

Therefore:
Create Method Stub (Editing\Refactorings\Create Method Stub)
Insert Method: After source method property.

Extract Method (Editing\Refactorings\Extract Method)
Insert new methods: Below the source method or property.

Extract Property(Editing\Refactorings\Extract Method)
Insert new properties: Below the source method or property.

Property To Method (Editing\Refactorings\Property To Method)
Insert method(s): After the source property.

Decompose Initializer (Editing\Refactorings\Decompose Initializer)
I don’t like an automatic “With block” so I turn this off (VB.Net Only)

Early Experience(Editing\Refactorings\Early Experience)

Hell Yeah :D
– The bleeding edge is where it’s at :) but perhaps this does not suit everyone.

Encapsulate Field(Editing\Refactorings\Encapsulate Field)
Insert New Property: Below the field. (Similar logic to other extractions)
When references to the field exist : Do not Replace anything.

I use properties for external access to a field. If I’m accessing the property from inside the class it’s a special case rather than the rule.

Templates (Editor\Templates)
I have always maintained my own little set of templates which I store in a Custom root folder. These need to be imported if I am starting from scratch. I suggest that you place any new Templates you create in a similar “Custom” root folder. This makes the export and import of these templates, all the easier.

Shortcuts (IDE\Shortcuts)
I like to place new shortcuts in a Custom folder. you’ll see a pattern in several of my choices for common keys. This is because I am already so well trained in the art of Alt+Tab

I assign Alt+` to CodeRushTrainingWindowToggle which allows me easy reach of said window, whenever I Forget something.

I assign Alt+1 to Refactor.

I assign Alt+2 to Navigate. I don’t use this as much as I’d like, but I’m learning (We never really stop learning eh?) Not got used to it yet, but I figure it’s the best place for it, given it’s proximity to Alt+1

I assign F2 to Refactor with a parameter of Rename. Ironically this is so that I don’t have to learn another shortcut. It is already deeply ingrained within me that I can rename a folder/file in windows explorer with F2, so it seemed like a good fit. this particular shortcut is already in CodeRush but is disabled. You can find it in the IDE\Shortcuts options page. In the 'Refactor!\Alternate Bindings' folder.



I guess that’s it for now. I’ll try to keep this post up to date with various changes I make to these settings. I assume there’s someone out there who’ll benefit :)


Tuesday, August 25, 2009

Why do I find CodeRush so indispensable?

 

I recently said “CodeRush has become an integral part of my workflow.”
and was asked by Braden Powers … “Do you have a blog post or something that explains why??”

I realized that I didn’t, and so here it is…

It comes down to the fact that I use certain facilities provided by CodeRush so often and without even thinking, that without CodeRush present, I end up spending several seconds staring at the screen wondering why some series of keystrokes isn’t doing what I think it should be.

Why should I ever be in such a situation. Well there are a couple of reasons.

  • Some of my colleagues have PCs that frankly cannot cope with Studio, so their chances of being able to cope with *any* addin are nil :( Using such a PC is sometimes unavoidable.
  • Sometimes I get caught on the hop. Between versions as it were. I have received a link to a beta or daily build of CodeRush and have been caught having already uninstalled my previous version and not yet having installed the new version. At this point it’s amazing how the universe almost always arranges a phone call to distract me… after which I forget that studio doesn’t currently have CodeRush.

So which facilities do I find to be most useful? Which ones to I use so often that I honestly forget that they are not a part of studio?

The answer is hard to define explicitly without currently being in one of the above scenarios but I will try.

Essentially the most used functions for me are those that are accessible from the CodeRush SmartTag menu. The Refactorings and the Code Providers.

Now between these 2 categories there are 225 separate functions. Obviously I don’t use all of these on a daily basis. If I were to be presented with the entire list every time I invoked the SmartTag, then I would go absolutely insane and dropkick CodeRush in a heartbeat.

CodeRush manages to provide a wonderfully intuitive interface here. Each Refactoring and Code Provider is intelligent enough to know if it is suited to your current context.

  • The Rename refactoring simply isn’t available if your caret is on a language keyword.
  • The Declare Class Code Provider isn’t available, unless the element under the caret is not currently declared and could potentially be a class.

This means that my one keystroke (I’ve rebound the CodeRush/Refactor key to ALT+1), I’m never presented with more than 5-8 options to pick from.

Next add to that, the fact that CodeRush moves the available items up and down on the menu based on your usage of those items. Constantly re-evaluating how far each should sit from the top of the menu.

Additionally, If CodeRush feels that there’s only 1 function which makes sense given the current context, then you can elect to have CodeRush not even show you the menu, but to move straight on to performing said function. So there’s even less for you to have to do.

ok Enough fluff… Which items do I use so often as to make Studio unusable without them

Note this is just my personal list.. CodeRush has much much more and these simply represent those facilities, whose absence actively slows me down.

First there are the Refactorings:

    • Rename
    • Extract Local
    • Extract Method
    • Extract Property
    • Inline Temp

I cannot stress enough how useful the above 5 Refactorings are in writing any code.

The ability to properly shape a solution as you go is phenomenal. I mean seriously… When you have to nail 2 bits of wood together … Do you use a rock or a proper tool like a hammer?

…Then there are the Code Providers

    • Declare Local
    • Declare Method
      • With parameters all in place based on your usage.
    • Declare Property
    • Declare Field With Initializer
      • Create a suitably named field of the correct type and assign the parameter to the field.
    • …and many more

…all available with a single keystroke (Alt+1 in my case)

Prototyping code has never been this easy

After this we are on to navigation:

  • Navigation
    • TabToNextReference
      • Place your caret on a variable and hit tab. CodeRush immediately underlines all references to this variable on the page and jumps to the next reference in the sequence. It should be noted that the “sequence” covers all references in your entire solution
    • References Tool Window(Shift F12)
      • The References tool window collates all references to any variable of your choice in a single location allowing you to seamlessly skip from one to another.

I feel I should also add add a quick section on the templating system here. I don’t use these nearly as much as I use the SmartTag facilities but it would be hard to since I’m sometimes hitting the CodeRush/Refactor key what seems like every 30 seconds or so.

So some of the template I use more than any others are:

  • Templates
    • Property declaration (pi, ps, pd8 etc)
      • Create properties of various types, with or without backing store, in only  couple of keystrokes.
    • ReadOnly Property declaration (ri, rs, rd8 etc)
      • As above but without the setters
    • Method Declaration (mi, ms, md8)
      • Same again but with methods.
    • Create Constructor (cc)
      • Generates a Constructor which takes various parameters based on your selection of any of the fields supported by the class.

Now It should be pointed out that prototyping any class is now insanely easy

c<space> – Class is created
vs<space>FirstName
vs<space>LastName
vi<space>Age

vi<space>GolfPar
4 Fields are now Created
cc<space><Enter> Constructor created
The constructor takes 4 parameters which are used to populate the fields.
Oh yeah and Readonly properties have been created to expose your fields. All of this is Totally configurable.

The final reason I can’t code without CodeRush is it’s extensibility. When I need something that CodeRush doesn’t have, I use it to create what I need using the DXCore plugin platform.

Checkout what others in the community have done with this amazing platform: Seriously check these out.


Friday, August 07, 2009

What’s your Windows 7 “Virtual Machine” Strategy?

I ask because it’s something I almost overlooked completely.

There are many Virtual PC style options on the market but up until now I have been using VPC 2007 SP1 because Its’ a Microsoft product and it’s free. Perhaps not the best strategy, but it worked … And I assumed that it was going to continue to work.

I was wrong.

I run several VMs under VPC at work and I need them to all continue to work.

But when I tried to run VPC2007 SP1 under Windows 7 (admittedly the RC) I was greeted with a dialog which suggested that VPC was not compatible with Win7.

“Ok” I thought, so where’s the version that is compatible. 

I found this … http://www.microsoft.com/windows/virtual-pc/download.aspx which is the Windows Virtual PC RC install. ( also the XP Mode RC install)

On the surface it looks good, but Microsoft seem to have player the same confusing trick they did with Messenger back in the day.

This is “Windows Virtual PC” (Win 7 Version) which is not the same as “Microsoft Virtual PC” (VPC 2007 SP1).

This *requires* AMD or Intel Chip level support (called VT Support on the Intel side) this is non- negotiable.

So it’s worth checking your chip to see if it provides VT support. The Intel side can use this utility.

However my work machine does not support this.

I am apparently stuck between the MVPC which runs on Vista and WVPC which runs on Windows 7 but only if you have VT support. At first looks this seems to mean No VM Support on Windows 7. This is not workable.

It seems that, at least for the moment, if you have an older (in some cases not that old) machine, and you require the ability to use a VM, that you’re up a certain creek without a paddle.

In my particular case I was lucky enough to have been introduced to VirtualBox (Yes I know you could use VMware, but AFAIK that’s not free and VirtualBox is just as free as Virtual PC. As indicated in the comments, VMWare Server is apparently Free.)

This is a wonderful app produced by Sun which seems to have little to no issues running VHDs created for use with VPC.

The one issue I encountered, was that I had to change the default network adapter from "PCnet-Fast III" to "PCnet-PCI II" before my guest OS would recognise the External network and the internet beyond.

That done though, everything seems fine, and the last of my Win7 worries have evaporated.

I will be installing Win7 RTM on both my home and work machines over the weekend :)


Thursday, August 06, 2009

New CodeRush Plugin: CR_MethodPreview

The other night I saw a tweet by Neal Culiner (@NCSoftware) regarding a plugin he’d like to see developed. 

Shortly there was a response was a tweet by Matthew MacSuga (@csharpbydesign). He mentioned that he’s asked for something like this a while back.

What they’re after, is a way to preview the code of a method, without having to visit that method.

I feel a little guilty because I remember Matthew mentioning this a while back. I think I started a debate at the time on "what should trigger the functionality” and we (well probably I) got bogged down in the details. Sorry Matthew :(

This time I just thought .. “Sod This” - (Wasting time that is, not talking to Matthew and Neal) - “Let’s just get something out there, and we’ll see where it leads afterward”.

So after a quick vote on the name of said plugin (Where Neal suggested the name and we all agreed :D) I was off to build a new plugin.

Where to start?

So I created a basic plugin and dropped an action in place. (For details please see a previous post)

From here I needed 2 things:

  • A function to determine which method to preview.
  • A function to actually do the preview.

There are some complexities in the original brief that I didn’t feel comfortable with initially.

  • “Select method based on method call under cursor”.
    • I have elected to use caret position in this first version.
  • “Hold a key down to see Preview”
    • I have elected to use a toggleable action in this first version.

Which Method?

So the first thing to do is to work out which method to display a preview for.

Some Terminology:
Given the sample…

    Public Sub Method1() 
Call Method2()
End Sub


  • “Method2” is known as the MethodReferenceExpression


  • “Call Method2()” is the MethodCall.



I would like this plugin to function from either of these 2 locations, so I need to return the declaration of the method to which either refers.



-------------------------------------------------------------

    Private Function GetMethod(ByVal Element As LanguageElement) As Method


        Dim Method As Method = Nothing


        Select Case Element.ElementType


            Case LanguageElementType.MethodCall


                Method = TryCast(Element, MethodCall).GetDeclaration


            Case LanguageElementType.MethodReferenceExpression


                Method = TryCast(Element, MethodReferenceExpression).GetDeclaration


        End Select


        Return Method


    End Function


-------------------------------------------------------------



To this method, I can pass CodeRush.Source.GetNodeAt(CodeRush.Caret.SourcePoint)



Later I can replace this with something which passes the element under the cursor, and I won’t have to change much at all.



Next we need to determine the code behind the Method in question.

-------------------------------------------------------------


Dim TheCode as String = CodeRush.CodeMod.GenerateCode(Method)


-------------------------------------------------------------


And now we have the code we’d like to render in our preview window. So lets crack on and create the preview itself.




The Preview Window



Building a preview window is easy… (Isn’t everything with the DXCore? :P)



The following function accepts the code and a location for the preview and builds the preview accordingly. It also places the preview on screen.



(The code to hide the preview has been omitted here but is even simpler.)



-------------------------------------------------------------

Private mPreviewWindow As CodePreviewWindow





Private Sub ShowCodePreview(ByVal Code As String, ByVal insertionPoint As SourcePoint)


    mPreviewWindow = New CodePreviewWindow(CodeRush.Documents.ActiveTextView, insertionPoint)


    mPreviewWindow.AddCode(Code)


    mPreviewWindow.ShowPreview()


End Sub


-------------------------------------------------------------





And so things come together in the main ToggleMethodPreview_Execute() as…





-------------------------------------------------------------


Private mShowingPreview As Boolean = False





Private Sub ToggleMethodPreview_Execute(ByVal ea As DevExpress.CodeRush.Core.ExecuteEventArgs) Handles ToggleMethodPreview.Execute


    If mShowingPreview Then


        Call HideCodePreview()


    Else


        Dim Method As Method = GetMethod(CodeRush.Source.GetNodeAt(CodeRush.Caret.SourcePoint))


        If Not Method Is Nothing Then


            Call ShowMethodPreview(Method, CodeRush.Caret.SourcePoint)


            mShowingPreview = True


        End If


    End If


End Sub


-------------------------------------------------------------



Summary



That’s pretty much all there is to it.



To use this plugin, simply bind a key to the “ToggleMethodPreview” action and activate it when your caret is in a suitable location.



For this plugin I wrote all of 42 lines of code including signatures.



Proof once again, as if you needed it, that the DXCore makes plugin writing ridiculously easy.



So now we have a first draft of “CR_MethodPreview”… go play… see what you think… And we’ll see where it goes from there.



-------------------------------------------------------------

For more DevExpress news, check out their Facebook page


-------------------------------------------------------------


How to: Bind a key in CodeRush.

If you would like to use CodeRush to bind a key, you're going to need to access the Options dialog.

This is available from the DevExpress Menu if you have the full version of CodeRush.
Alternatively, if you have CodeRush Xpress, you can press CTRL+Alt+Shift+O.

The left hand side of the options screen should look like this:

This screenshot was taken from the full version of CodeRush. Your version may be missing some items.

This might be because:

  • The 'user level' setting in the lower left of the options screen may be set to something other than expert.
  • You may be running CodeRush Xpress which has less features than the full version of CodeRush.

Select the 'IDE\Shortcuts' node as indicated in the screenshot.

The list of CodeRush bindings will appear:

As you can see, I typically create my shortcuts beneath a 'Custom' folder. this helps when it comes time to backup my customizations.

A new folder or shortcut can be created either from the Toolbar at the top of the shortcuts tree, or from a context menu triggered by right-clicking within the tree itself.

When you create a key binding, the right hand side of the screen will light up thus:

This section allows you to enter:

  • A keystroke which triggers your shortcut.
  • A command to execute once triggered.
  • Any params you wish to pass the command. (Optional)
  • A Context to limit your Shortcut’s use. (Optional)

Once you’ve filled out these elements, you are free to either create more bindings or save via the Ok or Apply button and start making use of your new binding.

----------------------------------------------------------------------------------------
Just a thought: Why not swing by the DevExpress Facebook page. You know you want to :)
----------------------------------------------------------------------------------------


Tuesday, August 04, 2009

CodeRush Templates – What makes them different?

The full version of CodeRush ships with several features not found in the Xpress version.

Simultaneously the most well known and least known about of these features is the CodeRush Template Engine.

So what can a Template do?

Well at it’s core, a template is nothing more than a bunch of text omitted on command.

Yup that’s it. :)

Type some characters hit <space> (the default template expansion key) and a whole slew of text is thrown into your editor as if you typed it yourself.

I know what you’re thinking….

You’re thinking … “but my clipboard can do that. What’s so special?”

Well you’re right… your clipboard can do that, but it has some comparative limitations.

For example:

  • Your standard windows clipboard can carry, at most, 1 set of text for pasting.
  • Visual studio has an enhanced clipboard which can carry about 20, but it does this in a way which forces you to have to cycle (Using that most painful of keycombos CTRL+Shift+V) through this ‘ring’ of clipped items until you’re, frankly, lucky enough to stumble upon the one you were looking for.  Your <deity of choice> help you if you happen to hit this key combo 1 time too many. (Round the cycle you go again)

So what does the template system do which makes it anything other than a glorified clipboard?

Well the Template system quite a few advantages.

  • Context Sensitivity:
    • You can learn a single template and use it in differing circumstances to produce subtly different effects.
    • Templates expand differently or not at all based on the context at the time of expansion.
  • Mnemonics Naming:
    • The template names are designed to be easy to remember and/or calculate.
  • Some Templates are Generic/Dynamic:
    • Dynamic Templates are those whose trigger is not defined entirely by their name, but have some external component.
  • The system of mnemonic naming, reduces the amount of learning to a bare minimum.
  • Language Agnostic
    • The vast majority of VB.Net and C# templates have counterparts in the opposing language which generates the equivalent code in that language. So once you are used to using CodeRush, switching languages is even less of an issue.
  • The CodeRush Template library is vast:
    • VB.Net has more than 920.
    • C#has more than 940.
    • Another 150+ dedicated to xaml, xml and html.
    • These figures don’t take into account the multiplier effect caused by some of those being Dynamic/Generic. for example, each template referencing the ?Type? dynamic list, is some 70 times more useful, than if it did not.
  • Templates have Links, Fields, Markers, Targets, Selection definitions and many other Text Commands and String Providers with which to augment the template they are embedded.
  • The template system is extensible.
    • You can create as many new templates as you like.
    • You can customize your templates with Text Commands and String Providers.
    • You can write your own custom Text Commands and String Providers in and .Net language.

Ok… So that’s something of a bulleted list… Let’s dig a little deeper…

Digging Deeper

Mnemonic Naming

A mnemonic is an aid to memory. Each character in the name (aka the trigger) of a CodeRush Template, represents a part of what it is going to generate. It represents what will happen when the template expands.

Lets take a simple example… ‘Variables’:

If you want to declare a variable of type ‘string’, you type vs<space>
If you want to declare a variable or type ‘double’, you type vd<space>
If you want to declare a variable of type ‘date’, you type vd8<space>

See the pattern? A similar logic works for properties:

If you want to declare a property of type ‘string’ you type ps<space>
If you want to declare a property of type ‘double’ you type pd<space>
If you want to declare a property of type ‘date’ you type pd8<space>

For readonly Properties…

If you want to declare a readonly property of type ‘string’ you type rs<space>
If you want to declare a readonly property of type ‘double’ you type rd<space>
If you want to declare a readonly property of type ‘date’ you type rd8<space>

A property of type string is ps<space>
A readonly property of type string is rs<space>
A method returning a string is ms<space>

Other mnemonic devices are at play all over the CodeRush Template library.

Context Sensitivity

As previously discussed, vs<space> expands to form a declaration of a variable of type ‘string’.

What hasn’t been show so far, is that, dependant on where this expansion occurs, several different expansions might occur.

  • If the caret (flashy vertical bar indicating where text is inserted) is positioned inside a class or structure, the expansion should declare a private field of type string.
  • If the caret is instead within a method, the declaration will be a local (changing structure and keywords, where appropriate in the case of say… VB.Net).
  • If the caret is within the brackets representing the signature of a method, then the expansion is appropriate to declare a parameter.

Similarly r<space> will create a readonly property with backing store of type Object, if expanded within a class.
However, if expanded within a method, it will yield the return keyword.

There are roughly 190 contexts shipping with CodeRush which can potentially be true or false. This allows it to have a pretty good idea of whether or not a given template is appropriate for your current situation.

CodeRush uses this information to streamline it’s operation, eliminating vast swaths of templates from consideration when they are simply not appropriate. Because of this, we *could* arrange to use a valid keyword, such as ‘switch’ or ‘select’, outside of it’s normal context allowing it to trigger a template expansion whilst leaving it inert, in it’s natural context so as not to disturb the natural flow of the developer.

Text Commands and String Providers

As you will no doubt have realised whilst expanding some of those previous examples, templates are not just static text.

Text Commands and String Providers are another example of how CodeRush Templates are a step above the available alternatives.

String Providers are akin to functions which return strings, in that they generate string values based upon some logic, which are then injected into the templates at the point from which they are called.

You can have a template which inserts the current date, time or username into a header string. They can also be used to inject the name of the current method, class, project etc.

One interesting use of a String Provider is to inject a value previously saved to a location in memory by another String Provider or Text Command. This has the effect of allowing 1 template to pass parameters to another. Also it means that a useful part of 1 template can be extracted and made available to be called by several other templates. This makes the library as a whole more efficient.

Text Commands are subtly different, they are closer to void procs (or Subs for those who use VB.Net like myself). They emit no text into the template they are placed within, but they can perform other tasks. Text Commands are used to Add References to your project, position the caret, indicate a selection, turn text into a field or link and many more things besides.

Links, Fields, Markers, Targets, BlockAnchors and Caret

These are some of the more common Text Commands you might find in CodeRush Templates.

  • Fields are used to wrap discrete sections of the output for further customization after expansion.
  • Links and TypeLinks are used to link sections of output together so that post-expansion customizations affect each linked area in the same way.
  • Markers (both hard and soft) can be added to the code to allow you to revisit a section of output and at a later time.
  • A caret (with an optional BlockAnchor) can be used to set the initial position (and selection) post-expansion.
  • …and a target can be used to set the final destination of the caret once all fields are filled.
Generic/Dynamic Templates

Some templates are defined a little differently to others. Dynamic (Sometimes called Generic) templates are defined such that their name (or trigger) is not hard coded as a single sequence. In fact it may surprise you to know that the templates we have been using up until now are just such templates.

The template vs<space> is not actually named vs. Instead it is named v?Type?. This is an indication to the template system, that it may use any mnemonic from a Dynamic List called Type (stored else where in the CodeRush settings) in place of the ?Type?. This particular list is provided by CodeRush and happens to contain approximately 70 different .Net types.

What this effectively means is that any template that happens to allow the use of the ?Type? list, can have it’s effective usages multiplied by 70. That’s quite the effect for a couple of lines of template.

Some Templates use dynamic lists more than once in their name, which causes their potential combination of uses to skyrocket. you may never use many of these, but it’s good to know the flexibility is there if you need it.

Extensibility

All templates that come with CodeRush are editable. You can customize them to your liking, or you can create entirely new templates using the same techniques as those who created this extensive library.

Further you can create entirely new Text Commands and String Providers for use in your templates as well as other features. Each is simply a component dropped on the design surface of a plugin and given appropriate code in it’s Execute or GetString methods. additionally you can create your own Dynamic Lists to hook your own templates up to.

What next…?

In a future post I will give some examples of Templates to be found in this vast library and show you how to use them to good effect. Additionally I’ll show you how to use some of the techniques described here to formulate your own templates.

----------------------------------------------------------------------------------------
Blatant Advert: Why not swing by the DevExpress Facebook page. You know you want to :)
----------------------------------------------------------------------------------------


Thursday, July 30, 2009

CodeRush vs CodeRush Xpress?

So what’s the difference?

Well CodeRush Xpress is what it sounds like. It’s a lite version of CodeRush which is FREE to all users of VS2008.

I’ll say that again …IT’s FREE……

It is not a trial.

It does not time out.
It does not have nag screens.

Here is a woefully inadequate Summary:

CodeRush Xpress:

  • > 50 Refactorings
  • Camel Case Navigation
  • Smart Cut/Copy
  • Tab To Next Reference ***
  • Highlight All References***
  • Quick Navigation ***
  • …Lots more I’m sure I haven’t remembered

CodeRush:

  • Everything from CodeRush Xpress (Above)
  • 57 Code Providers*
  • 168 Refactorings*
  • 122 Code Issues* (Code Analysis)
  • 25 Categories** of Templates (Insanely useful)
  • Intelligent Paste
  • Clipboard History
  • Selection Embedding
  • Selection Inversion
  • Code Metrics
  • Flow Break Evaluation / Region Painting.
  • References Window
  • “Jump to” menu (Navigation)
  • …and again many more I can’t even remember at the current time.

* Figures based on the pre-release copy of CodeRush 9.2 in front of me :)
** I’ve counted Top level Categories only, because to count the templates themselves, would take forever. There are way to many, and several of them take params based on a really cunning, and easy to learn system of Mnemonics. The number of potential outputs from these templates is quite frankly scary-cool.
*** Update: In version 10.1 of CodeRush Xpress MS has asked DevExpress to remove certain features whilst running under VS2010 for more details see my more recent post –> CodeRush 10.1 hits RTM


A few links for anyone looking to find out more about CodeRush or CodeRush Xpress

CodeRush Xpress:

Introduction and Download: Official Homepage of CodeRush Xpress
Walkthrough of many Xpress features: CodeRush Xpress for C# and Visual Basic inside Visual Studio 2008 - by Mark Miller
CodeRush Xpress Videos: Training Videos

Note: Something about the deal with MS involved the removal of the DevExpress Menu from the Xpress Edition.
The options, however can be reached through the use of CTRL+ALT+SHIFT+O.

You may also consider following the steps in this blog post by Nick Berardi, which instruct how to reintroduce the DevExpress menu. (Please note that the steps are intended for version 9.2.x of CodeRush Xpress)

CodeRush:

CodeRush is a superset of CodeRush Xpress. Which means that CodeRush includes everything already mentioned plus a whole lot more

CodeRush Homepage: Introduction and links
CodeRush Trial: Trial Download and Cheatsheets
General Feature Overview: Categorised List of Features
Feature Comparison CR vs CRx :  Moving up from CodeRush Xpress to CodeRush – A little old but still valid.
CodeRush Videos: CodeRush Training
RefactorPro Videos: RefactorPro Training

Community:

There are also some 3rd party plugins available:
[Most work with CRx, but occasionally some might require CodeRush(Full)]

Community written Plugins: Community Site Home Page
Help with writing your own plugins: Plugin Resources

Hopefully that should be enough to get you going…

I will try to keep this post up to date as things change, but it’s hard… both CodeRush and CRx continue to get better all the time.

[P.S If you have any (CodeRush related) questions you’d like me to try to answer, you can find me on twitter @ http://twitter.com/rorybecker]


Thursday, July 09, 2009

HowTo: Write a header plugin for Coderush

I was asked recently if I knew of any plugins for Coderush which would allow one to hit a key and inject a header into the current file.

The idea was that the header would be injected in a location within the existing file but not necessarily where the caret was currently residing.

My initial idea of “use a template” scuppered by this idea, as templates typically expand where your caret is.

But perhaps not.

I quickly rerouted my thinking an  came up with the following idea.

What about a new Action (what is an action?) which would take a parameter of which template to expand. It could drop a marker at the current location… Jump to the top of the current file, Expand the template there, and then collect it’s marker… Perfect right ? :D

So how does one do that then…

See my previous Tutorials for how to create a simple action plugin.

The Action Properties

In this case we will simply set the properties differently….
CR_ExpandHeaderProperties

…add some Parameters (via the Parameters property)….
CR_CreateHeaderParams1

… flesh out a few of their details…
CR_CreateHeaderParams2CR_CreateHeaderParams3  

…and write some different code in the execute routine of the Action.

As usual, the code is really what it’s all about:

The Code

What we need to do here is to drop a marker, Go inject the template text and then collect the marker.

The Main event looks like this:

-------------------------------------------------------------
Private Sub actExpandHeader_Execute(ByVal ea As DevExpress.CodeRush.Core.ExecuteEventArgs) Handles actExpandHeader.Execute
' Get Params Dim HeaderType As String = ea.Action.Parameters.Item("HeaderType").ValueAsStr
    Dim FullTemplateNameAndPath As String = ea.Action.Parameters.Item("Template").ValueAsStr
    ' Drop Marker
    CodeRush.Markers.Drop()
    ' Determine Insert Point
    Dim InsertPoint = GetJumpLocation(HeaderType)
    ' Expand Template
    Call ExpandTemplateAtSourcepoint(FullTemplateNameAndPath, InsertPoint)
    ' Collect Marker
    CodeRush.Markers.Collect()
End Sub
-------------------------------------------------------------

Then we’ll need to determine the location at which to insert our header. This is based on a passed parameter.

-------------------------------------------------------------
Private Function GetJumpLocation(ByVal HeaderType As String) As SourcePoint 
    Dim ElementRange As SourceRange
    Select Case HeaderType.ToLower 
        Case "file" ElementRange = CodeRush.Documents.ActiveTextDocument.Range 
        Case "type" ElementRange = CodeRush.Source.ActiveClassInterfaceStructOrModule.Range 
        Case "member", "method" ElementRange = CodeRush.Source.ActiveMember.Range 
        Case Else ElementRange = CodeRush.Documents.ActiveTextDocument.Range 
    End Select Return ElementRange.Start
End Function
-------------------------------------------------------------

…and finally we’ll need to actually inject the Header from the nominated Template…

-------------------------------------------------------------
Private Sub ExpandTemplateAtSourcepoint(ByVal FullTemplateNameAndPath As String, ByVal InsertPoint As SourcePoint)
    Dim TemplateName = FullTemplateNameAndPath.Split("\"c).Last
    Dim TemplateCategory = FullTemplateNameAndPath.Substring(0, FullTemplateNameAndPath.Length - TemplateName.Length - 1)

    Dim Template = CodeRush.Templates.FindTemplate(TemplateName, TemplateCategory, _
                                                   CodeRush.Documents.ActiveLanguage)

    Dim FinalText = CodeRush.Strings.Expand(Template.FirstItemInContext.Expansion)

    ' Again this isn't the best as we loose links etc... But it was a prety quick turnaround right ? :P
    CodeRush.Documents.ActiveTextDocument.InsertText(InsertPoint, FinalText)
End Sub

-------------------------------------------------------------

This last part expands the template into an in memory string which is then injected into the ActiveTextDocument at the previously calculated location. ...and we’re done.


Thursday, June 25, 2009

The ElementEnumerable Class

In our previous tutorial we showed how to use Methods like AllVariables and AllExpressions to extract information from some code in order to furnish the Code Metric subsystem of Coderush with additional Metric possibilities.

But what happens if you want to gather something that is not catered to explicitly? Perhaps you’d like to write an ExtremeMetric which counts Try..Catch information?

Let me introduce you to my good friend ‘ElementEnumerable’

ElementEnumerable

ElementEnumerable is exactly what it sounds like. It a class which is used for Enumerating Elements. It’s constructor takes a scope element, a Type filter and an option to recurs or not.

It implements IEnumerable and when used as an Enumerator, it will enumerate across the scope you handed it, stopping to pass out anything which matches what you asked it to filter.

We can create a MethodEnumerable for the current class thus…
e.Value = New ElementEnumerable(SomeClass, GetType(Method)).Cast(Of Method).Count

Our Variable Enumerator will be only slightly more complicated..

e.Value = New ElementEnumerable(SomeMethod, GetType(Variable), True).Cast(Of Variable).Count


The reason for the True param at the end is to allow The ElementEnumerable to recurse inside things like if statements in order to find variables declared deeper that the top level of the method in question.



In our previous example of a MethodEnumerable, we can safely assume that the methods we would like to find are all immediate children of the start point. If we had not made this specification, we could well have returned methods belonging to a nested class.


So if we wanted to count Try Statements, we could use….

e.Value = New ElementEnumerable(Method, GetType([Try]), True).Cast(Of [Try]).Count

…and of course you can do all kinds of calculations before you actually set this value.



So why don’t you go nuts and invent your own metric. Any questions? Just let me know :)


How To: Build your own CodeRush Metric

Well it’s been a long time, but I think I’ve finally found something I can turn into simple plugin.
-------------------------------------------------------------
Note: This tutorial assumes that you are familiar with LINQ, are coding your plugin in VS2008 and targeting a system with .Net 3.5 installed.
-------------------------------------------------------------

We’re going to provide a count of the number of variables declared in a given method.

This is an entirely contrived example. In the real world it might be used as an indicator of how complex a method is. However, you could also use the “Maintenance complexity” or “Cyclomatic Complexity” that comes with CodeRush :)

This theory this metric should involve:

  • Iterating through every node within the AST (Abstract syntax tree) looking for items representing variables.
  • Count these items and pass this count back to the DXCore for rendering by CodeRush

In practice this is a lot simpler than it sounds.

First you’ll need to create a new plugin. Once this is done, you’ll want to add a CodeMetricProvider to the design surface of the plugin. It can be found on the “DXCore: Extensions & Providers” tab of your toolbox and looks like this.CodeMetricProviderOnce dropped on the design surface, we should set a few properties.

ProviderName: ‘VariableCountMetric’
DisplayName: ‘Variable Count’
Description: Counts the variables declared within the member.
MetricGoal: Members
Warning: 10

Then handle the single event ‘GetMetricValue’.

The Theory

Your goal within the GetMetricValue, is to set e.Value based on some measureable quality of e.LanguageElement.

You could do anything here.. random numbers, length of member name, characters in method, characters in method if it were rendered in a different language :P All sorts.

In this case we will examine e.LanguageElement (the method) and calculate the number of variable declarations within it.

The “Warning” property is to give Coderush a value which is considered excessive for this metric.

Simples! :D

The Practice
Ok so how to count variables in a method?
Well the simplest way is…
-------------------------------------------------------------
SomeMethod.AllVariables.Cast(Of Variable).Count
-------------------------------------------------------------

So add this code to you handler and you’re done…
-------------------------------------------------------------
Dim Method As Method = TryCast(e.LanguageElement, Method)
If Method IsNot Nothing Then
      e.Value = Method.AllVariables.Cast(Of Variable).Count
End If
-------------------------------------------------------------

Ta Da…. Seriously go try it out…

If you get this to run successfully, then go have a look at some of the other “All” methods that hang off the method class..

Like AllExpressions, AllFlowBreaks, AllParameters or AllStatements. Similar methods exist on the ‘Type’ class.

Note: Remember to load your plugin via the “plugin manager” if you set it to “Load manually” when you created it (as you should have)


Friday, June 19, 2009

Coderush 9.2.0 Speed and Memory Improvements FTW!!

Recently Mr Mark miller posted on his blog about how much more efficient the next version of CodeRush was going to be.

In summary -> ZOMG This will be so cool".

So at the earliest opportunity, I requested access to the latest daily build of said product and was granted access

A few notes up front:

  • If you’re going to try this out, you need to uninstall 9.1
  • This version of 9.2 is a TRIAL version. It will expire eventually. Not sure when. I didn’t ask.
    • *YOU CANNOT* install this as a registered user… Nobody (Including me) has been given this level of access.
    • *Install as Evaluation* It works just as well :D
  • This is not the release version. It is a daily build. It did not go through the usual levels of testing.
  • There is a bug in this version which prevents some things from working unless you have installed everything (including the free bits)
  • The timings below were not done using a stopwatch but by me counting (1..1000..2..1000)

I have a solution I use every day at work so I thought I’d use that as the basis for my testing.

Some facts about this solution

  • It’s written in VB.net
  • It contains 13 projects (6 Class libraries, 7 Webapps/Webservices)
  • There are no project references in this solution
    • This is strange I know.
    • Instead we reference dlls built using nant as a part of our external build process.
  • According to this LOC program my solution has…
    • Number of lines = 61,358
    • Number of code files = 503
    • Number of code-generated lines = 6,563
    • Number of user-entered blank lines = 4,355
  • The .vb code files total some 3.5 MB(ish)

Some facts about the machine I use at work

WorkMachine
(click Image for large version)

WorkMachineDetail 
(click Image for large version)

So first I needed a baseline. I disabled all addins and re-loaded studio.

Studio at rest with nothing loaded, occupied [34,020 - 50,684]

(Note: Figures represent the values shown in Process Explorer for Private Bytes and Working set respectively)

I loaded my solution and timed how long it took to reach zero CPU usage within process manager.
It took approx 15 seconds to load my solution and afterward memory usage had risen to [150,740 - 193,556]
I built the solution and memory raised a little further to [170,640 - 209,184]

So this was the baseline.

What followed was several repetitions of this procedure inserting the loading of CodeRush 9.1 and 9.2 into the sequence.

In each case I restarted studio and reloaded CR where appropriate.

I will not detail everything here, but will present the summary figures.

CoderushFigures 
(click Image for large version)

So how does this break down?

Well basically it’s all in the bottom right hand corner.

So for my modest project… (after having built an on-disk cache during the first load of any given solution)

  • CodeRush has practically eliminated any previous overhead it added to the solution‘s load time. So it’s now as quick to use CodeRush as to not use it. :)
  • CodeRush saves between 45.2% and 58.5% memory depending on how you choose to judge it.

It is worth noting that these memory savings are likely to skyrocket as the complexity of your software increases.

Indeed, I have already seen a post on twitter from a user who has something more like 80% savings on memory.

I know I’m happy with my results … How about you ? … What results do you get ? :)


Wednesday, June 10, 2009

CR_ClearAllMarkers

I am something of an anomaly….

I’ve been using Coderush now for about 3 years and I *still* don't get ‘markers’. I'm an Idiot.. I have some kind of mental block. I just can't think that way for some reason.

I expect to remain ignorant/oblivious of their use in my day to day life, until I eventually meet up with Mark Miller some day and he has the opportunity to beat me until I come to my senses :D.

In the mean time however, I suffer from a particularly mild OCDesque affliction which cannot deal with their presence on my screen.

Because I don’t use them, they are noise. Small noise, but noise none the less. The fact that they are small and noisy is part of why I don’t like them… the other part is that they are everywhere.

I was explaining my psychosis to @Fredrikeriksson on twitter. I mentioned that whenever I see these little blue and red triangles in my code I have a compulsion to repeatedly hit Esc in order to clear my system of them.

Unfortunately for me, this has a side effect of causing my caret to lurch about inside my code like a demented puppy that just found a fresh roll of toilet paper. It was whilst explaining this little disadvantage, that I realized that I could probably knock up a plugin to deal with this problem in less than 2 minutes.

As it turns out, I was wrong.

It took a full 2 minutes and 15 seconds to develop and test. However the result of this short period of development is now available for all who feel the need to partake.

I give you CR_ClearAllMarkers.

In all honesty, it’s a sham of a plugin really. All I did was create a new action which called a pre-existing method within the DXCore. as usual all the hard work had already been done for me by the Coderush/DXCore team themselves.

In any case, I would like to take this opportunity to apologize to the Coderush Team. Sorry guys it's nothing personal :)


Monday, April 27, 2009

CR_HelloWorld – Your first DXCore plugin

So for your first DXCore Plugin, we’ll show you the traditional “Hello World” program…plugin style.

We’ll show you how you can execute any managed code from a plugin – Fun stuff

First up you’ll need to Create a Vanilla plugin. From here you’ll be able to add all the relevant pieces to create CR_HelloWorld.

 

Ok first Step… ensure you’re looking at the designer view of your plugin. If you’ve not renamed it this will be the “Plugin1” (cs or vb) file.

DXCoreDesignSurfaceSmall

Next locate the ‘Action’ component in your toolbox and place one on the designer surface.

DXCoreControls

The set an appropriate name and a few properties:

actSayHelloWorld

Finally handle the “Execute” Action and do something within it.

This seems appropriate:

-------------------------------------------------------------
Private Sub actSayHelloWorld_Execute(ByVal ea As ExecuteEventArgs) Handles actSayHelloWorld.Execute
    MessageBox.Show("Hello World")
End Sub
-------------------------------------------------------------

Ok well that’s the majority of the work done.

However you’re going to need some way to activate this action…

So hit F5 to run up a new instance of studio to debug your new plugin.

Once this new copy of studio is running, be sure to ensure your plugin is actually running in memory.

Next we will attach your new action to a shortcut….

Open up the DXCore options screen (DevExpress\Options) Note – You may need to use the previously mentioned 'registry hack' to get the DevExpress menu to show up, if you’re running one of the Free DXCore based products.

Next select the IDE\Shortcuts page from the left hand side and you should see something like the following.

DXCoreOptionsShortcuts

In the shot you can see (Click to view full image) I have created a new ‘keyboard shortcut’ ( which I did via a context menu within the shortcut tree) and then I have filled out the Key1 and command options.

Now you can have your copy of Studio say “Hello World” whenever you choose :)

Obviously this is a something of a contrived example but, as you can see, it would be easy to have studio execute any managed code you care to dream up in a similar way.


How do I test my DXCore Plugin?

A simple enough question but it deserves a bit of thought.

You’ll recall from my previous post on creating a plugin, I suggested indicating that your plugin was a “Community plugin”

The reason for this was to prevent multiple copies of studio from loading and thus locking the plugin dll that you were working on.

So this leads you to a small problem… How to get the DXCore to load your plugin if you have explicitly asked it not to?

Well here’s how…

Simply open up the plugin manager from the DevExpress\Tool Windows\Plug-in Manager.

 

Side note: If you are using one of the free DXCore products, then you may not have such a menu. In order to acquire access to this most useful of facilities you’ll need to do a bit of registry hackery.
The following solution was provided in the AlexS (Another very helpful DevExpress employee)  in the DevExpress IDE Tools Forums
-------------------------------------------------------------
Please invoke the Registry editor, add the "HideMenu" DWORD value to the following Registry key, and set its Value to 0:

HKEY_LOCAL_MACHINE\SOFTWARE\Developer Express\CodeRush for VS\9.1
This should make the "DevExpress" menu visible.
-------------------------------------------------------------

DevExpressPluginManagerMenuOption

…to reveal this…

PluginManagerHelloWorld

Simply double click the entry you would like to load and, after confirmation your action, the DXCore will load your plugin.

All should now be good and you can commence testing your plugin..


What is a DXCore Action?

An action is one of the components you can drop on your plug-in design surface.

When you do so it looks like this ....

DXCoreAction

It can be triggered via either a mouse or keyboard shortcut (found in the IDE shortcuts page of the options screen) or placed on a menu (for example the context menu of the Code Editor)

It is a derivative of ‘system.component’ adding a few properties…

 DXCoreActionProperties

…and events…

DXCoreActionEvents

Some of these are worth drawing special attention to.

Properties
ActionName: The name of the action as displayed to UI like the commands dropdown in the IDE\Shortcuts options page.
ButtonText: What text would you like to represent this action when it is placed on a menu?
CommonMenu: A list of some of the more common menus found around VS.
ParentMenu: An alternative to CommonMenu. Use the name of any menu you know of, to place the action on that rather than one of the ‘common’ ones.

Note: The placing of Actions on menus is entirely optional and CommonMenu and ParentMenu are mutually exclusive options.

Events
Execute: The main event (so to speak :)). Fired whenever the assigned shortcut is triggered or the representative menu item is chosen. This is how the Action does it’s stuff.

In my next post I will walk you through your first actual plugin … Yes we will be starting slow, but we’ll ramp up fairly quickly as the posts flow… so you’ll be knocking out your own custom refactorings and the like pretty soon.


Wednesday, April 15, 2009

CodeRush 9.1.3 Community plugin support.

In the latest drop of the IDE Tools, the community folder experience has been enhanced.

Previous versions of the installer placed the community folder within the DevExpress folder structure (beneath Program Files).

This new location has several benefits:

1.> Creating a new plugin should (untested) no longer require you to launch VS with Admin rights. since your plugin ins not being rebuilt under program files :)

2.> Uninstall will not remove community plugins. (Shouldn’t have anyway but this really seals it.)

3.> Community folder will be immune to path changes as the version numbers of the IDE Tools increase.

As of 9.1.3, the Default folder for community plugins is now “{My Docs}\DevExpress\IDE Tools\Community\Plugins”


Monday, April 13, 2009

Creating a new DXCore Plugin

[Updated: This post has been updated to account for some small changes in the 9.1.3 release]

There are certain steps you must follow in order to create a DXCore plugin of any kind. This blog post will outline and explain those steps.

So the first step is to create the right sort of project.

If all is installed correctly you should be able to find the 2 available projects (‘Standard Plug-in’ and ‘Tool Window Plug-in’) in the DXCore section under either the Visual Basic or Visual C# sections in the New Project dialog.

Initially I’ll suggest that you pick ’Standard Plug-in’ as you can always add the Tool window later if you need to.

FileNewDXCorePlugin

Once you’ve given your plugin a Name, and hit Ok, you’ll be presented with the Plug-in Project settings dialog.

 InitialPluginSettings913_thumb5

Plug-in Type: System Plug-in: will cause your plugin to be deemed a ‘System plugin’ Duh! But what does this mean? Simply put, system plugins are loaded ahead of non system plugins. 90% of all plugins have no need to do this… I have yet to use this facility in any plugin I have written.

Plug-in Type: Plugin: Will cause your plugin to be built to “IDETools\System\DXCore\Bin\PlugIns\”. I’m guessing that this is something that DevExpress do themselves. Although I see no reason not to use the Community option.

Plug-in Type: Community Plug-in: is a new option with version 9.1.3. This is due, from what I can see, to the new Community Plugin Path option. This option sets the compile path of your new plugin, to your current community folder (Setup when you first loaded CodeRush or RefactorPro or DXCore after installing 9.1.3.) This means that, if you accepted the default, your plugin will exist under your ‘My Docs’ folder and as such will not require you to Launch Visual Studio with Admin rights in order to compile your plugin. – You should pretty much always pick this option.

Checking ‘Load manually’ will cause an entry to be added to the ‘plugin manager’ (another plugin), which in turn will prevent the DXCore from automatically loading your plugin.

Why would you do this?

Well, suppose that whilst developing your plugin, you are suddenly required to do something else. (Heaven forbid that anything should come ahead of this most important work). What you do is you go and immediately fire up another copy of VS and you load what ever you need into that session and off you go.

The trouble is that (assuming that you’ve compiled your plugin at least once) DXCore has now loaded a copy of your unfinished/unpolished plugin into memory. This might not be a problem but there are 2 ways I can think of that might mean it is…

1.> You’re writing the most killer refactoring known to man, and you’ve just completed the ‘DeleteAllThisUselessCrap’ routine but haven’t quite gotten around to writing the ‘InsertGloriouslyShineyCode’ and if activated, without taking suitable precautions then you could be up the swanny.

2.> You might want to tab back to to some more development on your plugin whilst you’re waiting for the results of your latest check-in on your ‘Important project’, but unfortunately the copy of VS hosting your ‘Important Project’ is maintaining a lock on your plugin’s dll and as such you’ll be unable to compile it, much less test it.

So in order to avoid these scenarios, I always tick the ‘Load Manually’ tick box which then ensures that the DXCore never *automatically* loads my plugin. Then when I launch a copy of VS for testing it, I locate it in the plugin manager and double click it in there. At this point DXCore wakes up, notices the plugin and loads it. In doing this you have only loaded your plugin into the address space of a single instance of VS, which exists entirely for the purpose of testing your plugin. This also means that when you shut down this single copy of VS, you’ll be able once again to resume development of your plugin. Great huh?

Note: This setting is local to your development installation only and will not affect any users of your plugin.

Default Load Type

I asked AlexZ (one of the great brains behind the DevExpress IDE Tools) about the ‘Default load type’ setting (and most everything else as well :) – Alex is a great source of info) and he had this to say:

On Demand - plugin is loaded when some event happens for which plugin should work. e.g. if you plugin contains some action - then it will be loaded only when action is being executed. Or it may define context or string provider or any other provider - and plugin will be loaded when provider is really accessed.
On Idle - Plugin will be loaded on editor idle, IOW when VS editor is being idle.
At start-up - Plugin will be loaded on start-up - however it will add time to overall loading time.

So which one should you select.. well the answer is it depends.. Personally I typically leave the default of ‘On demand’ in place as this means your plugin should not affect the start-up time of VS. This might mean that you have a minor slow down as you activate your plugin for the first time, but it will not contribute to slowing down the start up time of VS.

So to summarize… I recommend that you tick the ‘Load manually’ option and leave everything else (except perhaps the name) exactly as default … then hit Ok

At this point VS churns away and provides you with a nice clean plugin project ready for you to create the greatest plugin known to man… after all .. that’s what you were going to do right :)

I am now contractually obligated to make you wait until the next instalment before I reveal anything else :)


DXCore Plugin Types

A single DXCore plugin dll can perform a single simple task or many different functions. These functions are added to a plugin by adding various components to it’s design surface. These components will need various properties set and events handled, but the process is typically quite simple.

These components include:

  • Action – A simple object which represents any arbitrary piece of Code you like. Placable on many of the VS menus and assignable to a keyboard or mouse shortcut (optionally in combination with a context) using the DXCore IDE\Shortcuts option page.
  • RefactoringProvider – Used to add items to the ‘Refactor’ Menu in RefactorPro
  • CodeProvider – Used to add items to the ‘Code’ menu in CodeRush. It differs from the RefactoringProvider in that by convention items placed on this menu are allowed to alter the functionality of the code they affect
  • IssueProvider – Used to add ‘Code smells’, ‘Warnings’ and the like to the CodeRush ‘Code Issues’ feature.
  • CodeMetricProvider – Used to provide additional metrics for both inline metrics and the Metrics tool window.
  • ContextProvider – Used to add items to the Context Tree. This in turn is used to indicate suitability of Templates, Shortcuts and other Coderush facilities.
  • NavigationProvider – Used to add extra Items to the Navigate SmartMenu
  • SmartTagProvider – Used to add a new section to the DXCore SmartTag menu. Items like the existing ‘Refactor’ and ‘Code’ menu sections
    StringProvider and TextCommand – used to enhance existing features like templates, selection embeddings, Selection Inversions and others. Both perform some function, but the StringProvider returns a value to it’s calling mechanism where the TextCommand does not.

Depending on the type of functionality you are after, you may not need to place any additional component on your plugin. The plugin object itself has several properties and events that, when properly used, can provide some very useful effects.

Over the course of the next few blog posts I am hoping to provide some insight into the general process of creating a plugin, as well as the facilities provided by each of these components.