Custom Templates

ReSharper templates enable you to quickly generate predefined code constructs. Many templates are provided ready to use; you can create new templates, edit existing ones and easily manage them.

Creating and using your own templates is a quick and easy way to help eliminate repetitive code or to automate common tasks. To demonstrate this functionality, I am going to show how to use custom templates to add log entries using the Apache log4net library.

Lets start with a class that looks like this:

    
    public class SampleClass {
        public void doSomething() {
            try {
                String value;

                value = getSomeValueFromDatabase();
                Console.Out.WriteLine(value);
            } catch(Exception e) {
            }
        }

        private string getSomeValueFromDatabase() {
            return null;
        }
    }

The first thing we want to do is to create a template that will allow us to add a new logger to a class.

To do this, we’ll open up he ReSharper Template editor, under the Visual Studio.Net menu
ReSharper -> Options…, and then in the options dialog, choose Live Templates.

ReSharper Options Dialog

Next, we’ll create a new template by selecting the User Templates item from the available templates and clicking the Create Template button . This will bring up the Edit Template dialog.

Now we can start to write our template, the first thing we want to do is to give our template an abbreviation. This is the name that we will use to activate this template and make it run, for this example, we’ll call this “logger”.

The next thing we want to do is to give our template a description, for which I will enter Create a new logger instance for a class.

Once these values are filled in, we are ready to write our template. In the Template Text box, we’ll fill in the value:

protected static readonly ILog log = LogManager.GetLogger(typeof($CLASS$));

You’ll notice the declaration $CLASS$. A word surrounded by a $ sign indicates to ReSharper that this is a variable that you want to do something with. In the section below Template Text, called Template Variables, ReSharper has automatically created an entry for $CLASS$ that looks like this:

The power of templates comes when you click the Choose Macro link. The macro that we want is called “Containing Type Name”. When the template is run, this variable $CLASS$ will run that macro. This will take our template text and replace $CLASS$ with the name of the type containing it. In our case, this will be SampleClass.

You’ll notice that there is a check box for this variable for Editable Occurrence. This allows you to have the user edit the value once it has been applied. We don’t want it for this case, so we will uncheck this box.

Now, click Save and you’ll see that you have a new User Defined template. Click Ok in the Options dialog to go back to your code.

Lets see this template in action. Under my class declaration for SampleClass, I will place my caret and hit Control-J, Insert Live Template. In this list that appears I will see my new template logger.

After hitting tab, I now have:

So now, every time I create a new class and I want to create a log field for it, I only have to use my new template to do it automatically.

Let’s do just one more example. For my code, in my try…catch block, I want to write an entry to the log file that looks lik this:
log.Error("[SampleClass::doSomething] An error as occurred", e);
But I want this entire line to be automatically created for me with the values already filled in.

Let’s create a new User Template, following the same procedure as before and create a new template that looks like this:

This template is a lot more complex then our last one and works like this. In our Template Text, $logger$.Error("[$CLASS$::$METHOD$] $MESSAGE$", $EXCEPTION$); we are using five variables.

When the template is run, these five variable will fill in the following information:

$logger$ ReSharper will suggest that this variable will be replaced by a variable in the current class of type log4Net.ILog
$CLASS$ This variable will be replaced by the name of the current class
$METHOD$ This variable will be replaced by the name of the method that this template is executed in
$MESSAGE$ This variable doesnt have a macro, but it is an editable occurrence. This will allow the user to tpe the specific error message in this spot once the template is run.
$EXCEPTION$ This variable will be replaced by a variable of the type System.Exception. Since this template is intended to run inside of a catch block, this will exist.

Finally, when we save and run this template, we see the following:

Step 1: We find our new template “le” and run it

Step 2: Our template is created with our editable area surrounded in red. We type in our message

Step 3: With our message typed in, our template is finished

Now, every time I want to write a log.Error entry, I can use my le template to do this automatically for me, saving me the trouble of writing it out each time.

As you can see, custom templates can be very powerful. If you would like more information on what you can do with custom templates, check out ReSharpers help contents. There is a lot of information available on what you are able to do when creating your own custom templates.

Jeff Pennal
JetBrains .NET Evangelist

This entry was posted in How-To's, ReSharper Tips&Tricks and tagged , . Bookmark the permalink.

3 Responses to Custom Templates

  1. Jens says:

    Regarding live templates ect.

    Is it possible (without digging to deep into code and macros) to add a Namespace include if you insert a specific template.

    in the above this would add a “using log4net;” among the other using’s in a file the first time the template was invoked.

  2. @Jens

    AFAIK you can’t tell a live template to add namespace imports automatically.
    So the workaround is to Alt+Enter one of symbols belonging to an unimported namespace, and choose a quick-fix to import it.

  3. Drew Noakes says:

    @Jens, @Jura, you can do this. Just include the full namespace in the template, then choose ‘Shorten qualified references’ (this is checked by default).

    So the above example would look like:

    private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof($CLASS$));

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>