Tag Archives: Visual Studio

Partial Classes to the Rescue!

I’m working with a fairly large codebase – a few of my base classes have several thousand lines of code.  Not huge, but certainly unwieldy when you need to be hopping around the codebase.  There’s just no great way to organize everything.  While some folks eschew regions, I find them useful when used sparingly and what I’ll call “correctly”.  In other words, regions never go inside a method, that can quickly lead to a mess; but they’re useful to group a bunch of related members and be able to quickly hide them.  In some cases, those members can and should be moved to a separate class, and in those cases that’s what I do.  But in some cases, a separate class doesn’t make sense.  Regions do.

But even that isn’t enough sometimes.  In my current codebase, I have a bunch of interfaces which my various classes implement.  Each interface defines 5-10 members, so they’re pretty tiny, but even that can get unwieldy.  My core base class implements 5 of those interfaces, which means that it has something around 40 methods just to implement its interfaces – that’s not getting into some of the core logic for that abstract base class, just its interface implementations.  It also has a bunch of private methods and properties which it needs to do its job.  Wading through all of that code can be a headache sometimes.  Worse, I’m still a little old fashioned and sometimes I want to (gasp) *print* some of my code to be able to analyze it and draw circles and arrows while working on it.  Regions don’t help when printing – everything collapsed inside the region gets printed.

That’s where partial classes come in. 

I’ve started breaking my larger classes into partial classes – one file for each interface.  Now everything related to ISecurable or IStorable, for example, is on one place.  Each code file is now closer to 7-800 lines of code instead of 3-4000.  Much easier to work with. 

The best part is, neither Visual Studio nor the compiler care.  The compiler happily combines the separate files together into the exact same MSIL as if they had been all in one big file to begin with.  Visual Studio doesn’t miss a beat, either.  Not only does it have no trouble with the separate files, it still shows me proper Intellisense across files:

SNAGHTML441cfcd5

Furthermore, Visual Studio is smart enough to show me all of the members of my class, even those defined in another file from the one I’m currently working in, and it even shows them dimmed so I know they’re in another file:

image

Other Visual Studio functions, such as Peek Definition, Go to Definition, Find All References, etc., continue to work as well.

Typically partial classes are used to separate generated code from developer-written code.  Other folks use them to allow multiple developers to work on the same class at the same time.  This is just one more case where partial classes provide real value.  I know some folks will disagree with this, and that’s fine.  To each their own.  To my mind, partial classes, like regions, provide significant value when used appropriately and in moderation.

One final point, I organize my partial classes a little differently than I think other folks might, and I think this helps keep things straight.  Every partial class in my code base is in a folder named for the class.  Each file of the partial class has the same base part of its name – the name of the class, but then it also includes the interface implemented in that file.  Here’s a view of Solution Explorer showing one of my partial classes (RepositoryItem):

image

Each interface gets its own file, and then there’s RepositoryItem-Core, which contains everything else for the class.

JavaScript: Deployment and Download

Series Contents

  • Part 1: Introduction and Basics
  • Part 2: Deploy & Download (this post)
  • Part 3: The Client Side Object Model *
  • Part 4: Functions, Objects and Classes
  • Part 5: Avoid the Global Namespace *
  • Part 5: Download & Caching *
  • Part 6: Efficiency & Performance*
  • Part 7: Testing *
  • Part 8: Professional JavaScript Development *
  • Part 9: Error Handling *
  • Part 10: Advanced Topics *
  • Part 11: Security *
  • Part 12: Implementing Business Logic *
  • Part 13: Tools and Resources *
  • Part 14: Wrap-Up *
  • Bonus: JavaScript in SharePoint 2013 *

*: Coming Soon…

Synopsis and Key Take-Aways

This article covers important considerations for the mechanics of using JavaScript in your custom solutions and concludes with the recommendations for using a SharePoint Document Library as the repository for your script files, and the Custom Action approach to getting the files downloaded to the user’s browser.  Other approaches are reviewed briefly and discarded

 

Deploy and Download

In the first part of this series, we did a very basic overview of JavaScript, not really touching on SharePoint at all.  In this posting, we’re going start touching upon some SharePoint-specific aspects of working with JavaScript.  So far, all we’ve done is type some JavaScript directly in to the Console of our browser, we haven’t needed a server.  Obviously, that is not realistic for a production scenario.

In a real-world situation, we will have one or more JavaScript files, called libraries, which contain our code and need to be deployed to the server and then downloaded to the user’s browser when we need to access the functionality provided by the library.  Typically these libraries will have a .js extension and will be included along with other files in our Visual Studio project.  That project will generate a WSP (solution) file which will be deployed to our server environment at either the sandbox or the farm level.  When the WSP is deployed, it will make our JavaScript file available for download.  We then need to make sure that the file is downloaded.

Getting Started

For the sake of this post, I’ll assume that you have already created a VS project using one of the SharePoint project templates.  It doesn’t matter whether you create a farm solution or a sandbox solution.  I’ve used the Empty SharePoint Project template.  Create a new JavaScript library by right-clicking on your project node in Solution Explorer and select Add | New Item on the context menu.  In the dialog box that pops up, click Web in the template category listing on the left and then select JScript File:

image

This produces a blank JavaScript file in the root of your project, which is fine for now; we’ll move it in a little bit.  The name of my file is the default JScript1.js and I’ll refer to this name throughout this post.  If you use a different filename, you’ll need to adjust references later in the post as appropriate.  Add the following very basic JavaScript code to the new file and save it:

function sayHello(){

    alert("Hello World");

}

This is about the simplest JavaScript function you could imagine, but it is sufficient for our needs – we’re focusing on getting our JavaScript deployed and downloaded in this post, not on actually writing JavaScript.

Now that we have a file with some JavaScript in it, we can move ahead with deployment and then getting it downloaded to the user’s browser.  First we need to explore some options for deployment to understand the best option for the majority of the scenarios we will encounter.

Deployment Options

In a production scenario, we need to place the file which contains our JavaScript functions on the server and have it downloaded to the client to be executed.  The first thing this means is that we need to identify a location on the server to which our JavaScript file can be deployed.  The only real requirement for this location is that it be URL-addressable so that the user’s browser can request it and download it.  In SharePoint, there are several locations that could fit this bill:

  1. The _layouts virtual directory
  2. Ghosted site pages
  3. A Document Library

We’ll touch upon each of those in the following sections, and rule out all but the last.  A few notes about the criteria used to rate each option:

  • Performance is a consideration, though not necessarily a huge one thanks to browser caching
  • I’d prefer to keep my approach to JavaScript downloading as simple as possible so I’m looking for the broadest applicability of each approach. Approaches that work across a wide range of scenarios will rank higher.
  • Ease of maintenance is important
  • Supporting multiple versions of a library is important
  • Supporting metadata about the libraries is important
  • Flexibility is important – I don’t want my choice for deployment to dictate anything about the approach to usage of the libraries if at all possible

_Layouts

Deploying our .js files to the _layouts virtual directory is the most like a “regular” ASP.Net site.  When the user’s browser requests the file, it is delivered to them straight from the file system of the server.  In SharePoint, deploying to the _layouts virtual directory is easy – especially if we are using the Visual Studio Tools for SharePoint.  While it is arguably the easiest location to which we can deploy our .js files, as well as the location which delivers the best download performance, it is unfortunately not the best location for our script files.  For one thing, it is not sandbox compatible.  It is not possible to deploy files to the _layouts folder in a sandbox solution.  Another problem is that it offers the least capability from a metadata and management point of view.  For these reasons, it is not a recommended location to which to deploy JavaScript files.

 

Site Pages

The next option is to deploy our script files as ghosted site pages using a SharePoint Feature.  This overcomes some of the limitations of _layouts pages but not all of them.  Unlike _layouts, site pages are fully sandbox compatible.  That’s a good thing.  From a performance point of view, in non-sandbox solutions (i.e. farm solutions), performance will be comparable to _layouts pages as the site pages will be delivered from the file system, even though we deploy them as site pages.  In sandbox solutions, performance will not be quite as good as the content will be served from the content database instead of the file system.  That’s not necessarily a bad thing, but it is worth mentioning.  The one thing that site pages does not address is the manageability of the script libraries.  Managing our files requires SharePoint Designer and there is still no effective means for managing metadata about our script files when deployed as site pages, so we will not be exploring this option any further.

Document Library  **Recommended**

The final choice for deploying script files is to push them to a document library via a Feature.  This is the recommended location for our script files.  Primarily this is because it offers us the most capabilities for managing those script libraries, as we’ll see in just a moment.  It is important to note, however, that deploying to a document library will have a slight performance impact when our files are requested and downloaded to the user’s browser.  Normally a known performance impact is something we would try to avoid.  However, in this case it is OK for one main reason –   JavaScript files are cached on the user’s machine and so they do not get downloaded with every page.  This means that we typically only incur that slight performance hit once per user.  The rest of the time, when the browser needs our JavaScript file, it pulls it from the local cache instead of re-requesting it from the server.  Thus the performance impact is avoided on all subsequent page loads.  If the user clears their browser cache, the file will be automatically redownloaded.

This works so long as you have repeat visitors (so the JavaScript files will be cached on the client), such as in an intranet or perhaps an extranet.  In Internet-facing sites, the performance implications may be more severe and the benefits of the document library somewhat lessened.  In that case, the _layouts folder may be a better option.

Deploying to a Document Library

Deploying JavaScript files to a document library is trivially easy, as you’re about to see.  We’ll begin from our very basic SharePoint project discussed above, containing just the single JavaScript library.  In order to deploy this file to a document library, we first need to make sure that the document library exists in our site. 

Note: If you know that this document library already exists in your site, you can skip this step.

 

Creating the Scripts library

In SharePoint 2010, we can very easily add an instance of the Scripts document library to our project:

  1. Right click on your project name in Solution Explorer
  2. Select Add | New Item
  3. Select the SharePoint | 2010 category from the list of installed template categories
  4. Select the List Instance template
  5. Change its name to Scripts
  6. Click Add

image

In the next dialog box, configure the options as shown and click Finish:

image

Add the JavaScript file to the Scripts document library

Whether we just created the document library or it existed already, we add our JavaScript file to it in the same manner:

  1. Right click on your project name in Solution Explorer
  2. Select Add | New Item
  3. Select the SharePoint | 2010 category from the list of installed template categories
  4. Select the Module template
  5. Change its name to ScriptFiles
  6. Click Add
  7. In Solution Explorer, delete the Sample.txt file included in the ScriptFiles module
  8. In Solution Explorer, click on the JavaScript file we created earlier, drag it and drop it on the ScriptFiles node.
  9. If the Elements.xml file for the ScriptFiles module is not open, double click it in Solution Explorer to open it
  10. Notice that the Elements.xml file has been updated to include a reference to the file we just added to the module
  11. Change the XML in the Elements.xml file to look like this:
<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Module Name="ScriptFiles" Url="Scripts" List="101">

      <File Path="ScriptFilesJScript1.js" Url="JScript1.js" Type="GhostableInLibrary" />

</Module>

</Elements>

     

That’s all you need to do to make sure that your JavaScript file is properly deployed to your SharePoint environment.  If you’d like to test it out, hit F5 and when the browser comes up, navigate to <site URL>/Scripts.  You will see your JavaScript file listed:

image

Getting the file deployed is only half the battle.  Now we need to get it downloaded to the users browser so it can be used.

Downloading Options

JavaScript libraries are useless if they never leave the server; they must be downloaded to the user’s browser in order for the code they contain to be executed.  Similar to getting our library deployed, there are several options for getting it downloaded.  We’ll explore each option, discussing its pros and cons before declaring a winner.

A couple notes about the criteria I’m using to evaluate these options:

  1. Performance is a consideration, though not necessarily a huge one thanks to browser caching
  2. I’d prefer to keep my approach to JavaScript downloading as simple as possible so I’m looking for the broadest applicability of each approach.  Approaches that work across a wide range of scenarios will rank higher.
  3. I’m looking for the broadest reach when deploying.  I want one place to manage all of my JavaScript downloads.  I am not interested in deploying specific libraries only to specific pages in my application or conditionally downloading libraries based upon some criteria.  The vast majority of your JavaScript is likely to be used in multiple places so combining it together and downloading it in a small number of requests and taking advantage of browser caching makes sense.  While it is true that some JavaScript will only be needed on certain pages, it is far better to use a delayed loading or script-on-demand approach (discussed in part 11 in this series) to control those downloads.
  4. Compatibility with a delayed-loading scheme such as SharePoint’s Script On Demand is important

ScriptLink Control

The ScriptLink control was introduced in SharePoint 2007 and is still available in 2010.  Its main responsibility is to cause a JavaScript file to be downloaded to the user’s browser.  It does this by ensuring that the proper <script> tag is written into the HTML stream.  While the ScriptLink control is often recommended, I am going to shoot it down for two reasons:

  • it is not sandbox compatible.  Say what you will about the sandbox, and even toss in the fact that it is not a recommended approach for SharePoint 2013, it is an option in 2010, is the only option for server-side code in Office 365 and therefore important, at least for now.  As SharePoint and SharePoint Online evolve, this will need to be revisited.
  • it is hard to maintain as needs change.  In this way, it is similar to adding the <script> tags directly to the master page – changing it requires editing the master page in SharePoint Designer, which is something that should be avoided.

It is unfortunate that the ScriptLink suffers from these drawbacks, because it does provide value that we’re going to be hard-pressed to replicate.

Master Page Script Tags

Adding <script> tags to your master page is just not a good idea.  They’re hard to maintain, hard to work with initially, don’t travel well if you switch master pages, require SharePoint Designer to edit and various other problems.  While they may seem initially like a good idea, they’re just not in the long run.  Don’t do it.

Web Part

This option entails using the dreaded Content Editor Web Part to add a <script> tag directly to a page.  This is troublesome for a few reasons:

  • It is page-specific.  It only impacts the page to which you add it.  While this may seem like a good thing, it is not.  There are many pages in SharePoint that you can not add a web part to – how will you get your JavaScript onto those pages?  It also means that you need to add this web part on to every page upon which you want the JavaScript available.  If your needs change, there are a lot of places that you will now need to change.
  • It does not version well, cannot be included in source control and makes debugging more difficult.  These all fall under an umbrella of professional development disciplines and the CEWP fails miserably here.

Custom Action   **Recommended**

Adding the HTML to our page via the SharePoint Custom Action element offers many advantages and no disadvantages.  It is easily the best option:

  • It is fully sandbox compatible and fully farm compatible.  This means that I can use the same approach no matter how my solution is being deployed.
  • It is global – all pages in the scope at which we activate its Feature (Site or Site Collection) will have the appropriate HTML added to it
  • It is flexible and easy to maintain.  We take advantage of the SharePoint Feature framework to be able to turn the functionality on and off at whatever scope we need it
  • There are no performance penalties to using the Custom Action
  • It is fully compatible with SharePoint’s Script on Demand functionality and various other delayed loading schemes we’ll talk about in part 11 of this series. 

Therefore it is easy to declare the Custom Action as the best option for getting our JavaScript files downloaded.  The next section walks through how to accomplish this.

Downloading with a Custom Action

Adding the necessary HTML to our pages to cause our JavaScript files to be downloaded with a Custom Action element is easy:

  1. Right click on your project name in Solution Explorer
  2. Select Add | New Item
  3. Select the SharePoint | 2010 category from the list of installed template categories
  4. Select the Empty Element template
  5. Change its name to MyJSFile
  6. Click Add

Add the following to the Elements.xml file that Visual Studio creates and opens for you (placing it between the opening and closing Elements tags):

<CustomAction

    Location="ScriptLink"

    ScriptSrc="~Site/Scripts/JScript1.js"

    Sequence="10"

    Id="MyScriptLibrary"

/>

That’s it. SharePoint will now add the following to every HTML page in our site:

document.write('<script type="text/javascript" src="/scripts/jscript1.js"></' + 'script>');

This will cause our custom JavaScript library to be download (if it is not already cached on the client) and made available for use.  The functions in our library are now available to be called and executed.  Notice in the Custom Action element the use of the token ~Site.  When activated within SharePoint, this will be replaced with the URL of the site at which the Feature is activated.  Another useful token is ~SiteCollection, which gets replaced with the URL of the site collection.

If you’re curious why SharePoint adds the tag using a document.write instead of simply adding the <script> tag, it’s a mechanism for overcoming some quirks in how browsers download and parse JavaScript files. Without going into too much detail (which I’ll do in another post), it prevents one script from blocking the download of other page elements (scripts, images, CSS, etc) while the script is downloaded and parsed. More on that in a separate post.

 

To test this out, simply hit F5 to deploy and run your code.  After the browser opens to the homepage of your site, type the following into the address bar of the browser: javascript:sayHello(); and hit Enter.  The results should look something like this:

image

Our JavaScript code in the library (the sayHello function defined earlier) ran and popped the alert box up on the screen.  A very simple example, but sufficient to test out our process.  We’ve successfully deployed a JavaScript library to SharePoint and had it downloaded to the client.  Later in this series we’ll be developing more complex JavaScript libraries to begin offering real world functionality, but we’ll take advantage of the same mechanisms we’ve covered in this post for deployment and download.

Other Considerations

There are a number of tangential topics that need to be addressed in order to wrap up any discussion about deploying and downloading JavaScript libraries – improving download and caching, overall performance, etc.  These topics will be addressed in parts 5 (Download & Caching), 6 (Efficiency & Performance) and 10 (Advanced Topics). 

Wrap Up

This post has answered the question of “What is the best way to deploy my custom JavaScript to SharePoint and then have it get downloaded to the user’s browser?”  We’ve discussed a number of options and whittled down to the best approach – document libraries and Custom Action elements.  No matter what functionality we’re looking to introduce – form the simplest of examples (such as the project used here) to the most complex of scenarios, this approach will work equally well.