Cool Tool - Refactor!
Prologue
I've been playing with redesigning some of our website lately, and in the process I have been creating a number of user-controls for the website. In an effort to make them more usable on any number of pages, I started adding properties instead of hard coding the information so the information could be added in the html design as an attribute. In the process of creating so many properties, I found (ok, was referred to) a tool that is VERY cool.
Problem
Seems to me like there ought to be a way to have Visual Studio automate some of the stuff that it doesn't currently. If you remember back to VS 6, you'll remember that it didn't automatically add 'end' statements like it does now, and what a great improvement that has been. Wouldn't it be nice to be able to generate a variable and then make a property out of it? How about the changing the order of your parameters in your code and having the code automatically update? Well, Refactor! lets you. If it didn't do anything other than this, it would likely be worth downloading and installing, but it does more.
Solution
At the risk of sounding like a commercial for Refactor!, I thought I'd share this cool tool that I absolutely love!. Normally I'm pretty leery about downloading and installing tools unless they have a significant benefit. It has to do something that I didn't want to do by hand, or was just a pain to do that way. I downloaded and installed Refactor! and haven't regretted it for a minute.
Let's get started. Download Refactor! and install it. Now, open a new blank website. Create a blank web form if you don't already have one, and then create a new usercontrol and name it MyAdBanner.ascx. Next, create a folder named 'Images' and place a couple of images in it.
I'm in the process of putting together a new homepage for the company. One of the things they would like me to do is make the images that display in the content section of the main page rotate. I had an idea, how about using the ad rotator and then I wouldn't need to write much custom code. Problem is that I want Marketing to just upload the pics to a folder and then randomly pick one. Ad rotator requires a datasource (OR to use the adCreated event, which we'll use in a minute). But then I'd have to hard code the location the images and I have at least 3 locations, one for each section (I'll be using 3 of the rotators, each looking in a different location). So I decided to extend the ad rotator just a little so I can pass in the location to search.
Open your MyAddBanner.ascx and drop an Asp:Adrotator control on it and name the control 'theAdRotator'. Next, let's go into the code behind for the MyAdRotator.ascx control and add the following import statement at the top:
imports System.IO
and lets add two helper functions below, add the following functions:
Private Function RetrieveRandomFile(ByVal vsFolder As String) As String
Dim dirInfo As DirectoryInfo = New DirectoryInfo(Server.MapPath(vsFolder))
Dim icount As Integer = 0
Dim fiFiles As FileInfo() = dirInfo.GetFiles()
Dim iRandom As Integer = GetRandomNumber(fiFiles.Length - 1)
For Each file As FileInfo In fiFiles
If icount = iRandom Then Return file.Name
icount += 1
Next
End Function
Private Function GetRandomNumber(ByVal viMaxNumber As Integer) As Integer
Return CInt(viMaxNumber * Rnd())
End Function
The RetrieveRandomFile function will take the folder passed in and return a random filename from the folder and GetRandomNumber... well, you know. Finally, create a page to test our control on and drop your custom control on it.
Add properties in a snap
In our rotator, we'll use the Ad's AdCreated method to pull an image and then display it. We also want to give the ad alternative text, and a URL to navigate to when clicked. We could hard code all these things, but then the control wouldn't be interchangeable in other places. So we'll add some properties to our user control so we can specify these settings in our webpage as an attribute to the user control. In the past to create a property, we would have to type something similar to this:
Private _PathToImages As String 'variable declaration
Public Property PathToImages() As String
Get
Return _PathToImages
End Get
Set(ByVal value As String)
_PathToImages = value
End Set
End Property
Granted, VS will create the stub for you if you create the property line, but now we can do it much more easily. With Refactor installed, add a private variable declaration to the top of your document:
Private _PathToImages As String 'Variable declaration
Now comes the fun part, right click on the variable name and select Refactor!->Encapsulate Field. You'll notice that you get a red 'insertion line'. Refactor! is asking where to insert your
property. Use your arrow keys as specified in the instructions, and move the insertion line down below your variable and press enter. Bam. New property in a snap. Have 10 or 15 properties to create? No prob. Create the variables, and then use Refactor to generate the properties.
One downside. Need a read-only property? Refactor! only generates Read and Write properties, you'll have to modify the property as read-only and remove the set statement from the block. Still, very powerful. Also if you have used the variable anywhere before encapsulating it, Refactor! may offer to replace the instances of the variable with the property depending on the circumstances.
Rearranging parameters
Ever put parameters on a function then decided later that you really wanted to put them in a different order? Refactor! can help. Let's do an example. Modify your RetrieveRandomFile() function declaration to the following:
Private Function RetrieveRandomFile(ByVal bAddFolderPath As Boolean, ByVal vsFolder As String) As String
and change the if then statement in your for loop to look like this:
If icount = iRandom Then
If bAddFolderPath = True Then Return _
vsFolder & "/" & file.Name Else Return file.Name
End If
Finally, change the line in your adCreated event handler that assigns the ImageURL to:
e.ImageUrl = RetrieveRandomFile(True, "~/Images")
Ok, so we added a new parameter, but what if we wanted to make the bAddFolderPath parameter optional? We'd need to put it at the END of the declaration. But then we'd have to find all the instances in our code and change those too... Enter Refactor! Right click on the

parameter to move and select Refactor!->Reorder Parameters. By pressing the arrow keys, you can swap the parameters around and Refactor should then update the places that call the function to match the new parameter order. Now we can added to optional keyword if we so choose. One downside, Refactor is supposed to correct your code throughout, but I'm not getting to do to that correctly. Maybe there's a newer version that corrects the bug.
Epilogue
There are a number of other things that can be done using Refactor! This only represents two of them. I have found the functionality EXTREMELY useful, and I just thought I'd pass it on in case you haven't had a chance to play with it.