Fear and Loathing

Gonzo blogging from the Annie Leibovitz of the software development world.

  • Automatically Publishing NuGet packages from GitHub

    About an hour ago I didn’t have a MyGet account (although I knew about the service) but did have a repository on GitHub with a package that I was manually updating and pushing to NuGet. Thanks to a recommendation from Phil Haack and an hour of messing around with some files I now have a push to GitHub updating my NuGet package with a click of a button. Dead simple. Read on to get your own setup working.

    I’m currently in the midst of a reboot of Terrarium, a .NET learning tool that lets you build creatures that survive in an online ecosystem. More on that later but right now I’ve setup a NuGet package that you add to your own creation to get all the functionality of a creature in Terrarium. The problem was is that I was manually editing a batch file every time I built a new version and pushing that build up to NuGet.

    This is 2014. There must be a better way. We have the technology. We have the capability to make this process easy.

    austin

    Thanks to a few tweets and one suggestion from Phil Haack I checked out MyGet. At first it didn’t look like what I wanted to do. I didn’t want package hosting, I wanted to build my package from GitHub and publish it to NuGet. After looking at a few pages I realized that MyGet was really a perfect way to setup “test” packages. Packages I could push and push and push and never make public then with the click of a button publish the version from MyGet upstream to NuGet. In addition to a few pages of documentation on MyGet I stumbled over Xavier Decoster’s blog post on how he does it with his ReSharper Razor extension. The post was good and had enough steps to get me going. The MyGet docs are there but the screenshots and some of the steps are a little obscure (and didn’t always match what I was seeing in my browser) so hopefully this post will clear things up and give you a detailed step-by-step on how to do this (with the current version of MyGet, it may change in the future).

    What You’ll Need

    You’re going to need a few things setup first for this to work:

    1. A GitHub repository. BitBucket is also supported as well as others but I’ll document GitHub here. Check out the MyGet documentation on what they support.
    2. A MyGet account. I hadn’t signed up for one until about an hour ago so this is easy (and free!)
    3. A NuGet account.
    4. A .nuspec file for your project (we’ll create it in this post)
    5. A batch file to build your package (again, we’ll create it later)

    MyGet Feed

    You’re going to need to create a MyGet feed first before anything. So once you have an account you’ll add a feed. There are various places on MyGet to add one (and I think once you verify your account you’re thrown into the screen to create one). In the top login bar next to your name you’ll see a file icon that says “New Feed”

    image

    There’s also a “New Feed” button in the Your Feeds box on your activity stream page.

    image

    Once you click it you’ll be taken to a page where you enter the details of your new feed.

    image

    Enter a name for the feed. The first part of the URL is already filled in for you but you specify whatever you want. This will be your URL that you’ll enter into the Package Manager to consume your feed. You can also enter a description here.

    Next you get to determine how your feed is to be used. By default it’s public but you can also create a community feed (where anyone can push and manage their own packages on the feed).

    image

    With a paid account you can also have a private feed where you invite users to access it.

    Click on the Create feed button to finish the setup. Once you create the feed you’ll be dumped to the main page of the package where you can select various settings to configure your package feed. By default there’s nothing there so we’ll build up our package.

    image

    Getting Your Code

    First thing you want to do is add a Build Service. A build service is a mechanism to tell MyGet how to build your project. This will clone your GitHub repository on MyGet and build your package. Detailed information about the Build Services can be found here.

    Click on Build Services then click on the Add build source button. This will allow you to select a build source where you’ll pull your code from.

    image

    Here you can see you can add a GitHub repository, BitBucket, CodePlex, or Visual Studio Online service (or you can add one manually).

    Choose GitHub and you’ll be asked to authorize MyGet to interact with GitHub (along with maybe signing into GitHub). Once you authorize it you’ll be shown a list of repositories on GitHub you can select from. Choose the one you’re going to build the package from by clicking on the Link? checkbox and click Add (some repositories below are obscured but yours won’t be).

    image

    Once you add the build source you now have the information to setup GitHub for the webhook. Expand the build source to show the information MyGet created for it and you’ll see something like this:

    image

    Initially you won’t have any builds but this is where you’ll see those builds and their status. What’s important here is the Hook url. This is the value we’re going to use on GitHub to trigger MyGet to fetch the source when a push occurs (and build the package).

    Copy the Hook url (there’s a small icon you can click on to copy it to your clipboard, typing is for weenies) and head over to your GitHub project you selected for the build source.

    Webhooks

    On GitHub in your repository go to Settings then click on Webhooks and Services. Click on Add webhook to show this dialog:

    image

    In the Payload URL paste the Hook URL that you got from MyGet. Leave the Content type as application/json and the radio button trigger to just work off the push event then click Add webhook.

    image

    This will add the webhook to your GitHub repository which, on a push to the repo, will trigger MyGet to do it’s stuff.

    Building

    Now its time to setup your package creation in GitHub and create a package. Remember, MyGet is going to be doing the fetching of the source code from GitHub and compiling and packaging. The trigger will be when you push a change to GitHub (you can also trigger the build manually from MyGet if you need to).

    By default MyGet will search for a variety of things to try to figure out what to do with your codebase once it gets it. While it does look for .sln files and .csproj files (and even .nuspec files) I prefer to be specific and tell it what to do. The build service will initially look for a build.bat (or build.cmd or build.ps1) file and run it so let’s give it one to follow.

    Xavier provides one in his RazorExtensions repository so I (mostly) copied that but he’s doing a few things to support his plugin. Here’s a more generic build.bat you can create that should be fine for your project:

    • Line 2-5: These lines setup the configuration we’re going to use. This would be “Release” or “Debug” or whatever you have defined in your solution. If it’s blank it will use “Release”.
    • Line 7-10: This sets up the PackageVersion value that will be passed onto NuGet when creating the package. Again, if it’s blank it will use 1.0.0 as the default.
    • Line 12-15: Here we’re setting the nuget executable. If you have a specific one in your solution you can use it, otherwise it’ll just use the one available on MyGet (which is always the latest version)
    • Line 17: This is the msbuild command to run your solution file. My solution file is in a subfolder called “src” so I specify that way, yours might be at the root so adjust accordingly. The %config% parameter is used here to select the build configuration from the solution file. The other values are for diagnostic purposes to provide information to MyGet (and you) in case the build fails.
    • Line 19-21: Here I’m just setting up the output directories for NuGet. All packages will get put into a folder called “Build” and follows the standard naming for NuGet packages. Right now I just have a .NET 4.0 library but other files may come later. Build up your package folder structure accordingly (the docs on NuGet describe it here).
    • Line 23: Finally we build the NuGet package specifying our .nuspec file (again mine is in a subfolder called “src”) and the version number. The “-o Build” option is use the Build directory to output the package.

    Okay now we have a build.bat file that MyGet will run once it grabs the latest code from GitHub. Commit that (but don’t push yet, we’re not ready). Next up is to build the .nuspec file that will tell NuGet what’s in our package. You can create the .nuspec file manually or using NuGet to scaffold it for you (docs here). There are also some GUI tools and whatnot to build it so choose your weapon.

    Here’s my .nuspec for the Terrarium SDK:

    Pretty typical for a .nuspec file and pretty simple. It contains a single file, the .dll, that’s in the “lib/net40” folder. A few things to note:

    • My assembly is in the project directory but the .nuspec file is in the “src” folder so the package contents are relative to where the .nuspec file is, not where the system is running it from (which is always the root with MyGet)
    • We use the $version$ and $configuration$ token to replace paths and names here. These are set in the batch file prior to invoking NuGet.

    Okay now we’ve got the .nuspec to define our pacakge, the source code wired up to notify MyGet, MyGet to get it on a push, and a batch file to create our package.

    Push the code changes into GitHub and sit back. You can go to your Build Services page on MyGet for your feed, expand the chevron next to your feed name, and watch an automatically updated display pull your code down and create your package.

    If things go wrong feel free to ping me and I can try to help, but realize that everyone’s setup is different. Check the build log for immediate errors. When MyGet fetches your repository it’ll clone it into a temporary directory and then start looking for build.bat and other files to invoke. That’s why we want to put our build.bat file in our root (mine isn’t but I’ll probably change that at some point) so we can get his party started.

    A Package Is Born

    Once you have a successful build you’ll see your new package under the Packages section.

    image

    Cool. You can click on the Package Id to see more detailed information about the package and also manage old releases. Unlike NuGet, MyGet let’s you delete packages rather than just unlist them.

    One thing to note here is the version number. Where did that come from? In the screenshot above my version number is 1.8.0-CI0007.

    MyGet follows Semantic Versioning (which is a good thing). I do recommend you give it a quick read and consider adopting it. It’s easy and lets people know when things are potentially going to break (if you follow the 3 simple rules about major, minor, and patch version). Semantic Versioning regards anything after the patch number to be whatever your want (pre-release, beta, etc.)

    So about that build version. Go back to Build Services in MyGet and for your GitHub source you’ll see a button next to Build called Edit. Click it and it’ll bring up the details about the source that lets you configure how the code is fetched from GitHub.

    image

    So down a bit you’ll see a section called Version. Here you can set (or reset) a build counter. Each build on MyGet increments the counter so you know how many times the system was built (you can also use this to track what version is available or how far it’s drifted from source control or different builds in different environments, etc.). The version format field lets you enter your Semantic Versioning formatted value and use {0} as a placeholder for the counter. By default it's set to 1.0.0-CI{0} meaning that your first build is going to be labeled 1.0.0-CI000001 (the build number is prefixed with zeros).

    That’s where it came from so anytime you need to bump up the major, minor, or patch version just go here to change it. As for the extra bit we’ll get to it shortly but the default version works and won’t make it’s way into our “production” versions of our package.

    Consuming the Package

    Now that we have a package we can add it to our package sources in Visual Studio and install it. Again this post is written from the perspective of using MyGet as your own personal repository where you can test out packages before releasing them to the public. While public packages are the default (and free) version on MyGet, you can keep pushing pre-release versions up to MyGet until you’re happy with it then “promote” it to NuGet.

    In MyGet click on your package and select Feed Details from the menu. You’ll see something like this:

    image

    This is your NuGet feed from MyGet for this package. Copy it (again with the handy icon) and head into Visual Studio.

    In the package manager settings add this as a package source. I just add it while I’m developing and testing the package and then disable it (so it doesn’t get confused with the “official” NuGet server). You can easily flip back and forth between packages this way.

    image

    I just name the MyGet feed after the package because it’s for testing. Activate the MyGet feed (and to avoid confusion disable the NuGet one) and then return to the managing pacakges for your solution. Select your MyGet feed from the Online choices in NuGet to see your package.

    Remember that MyGet is (by default) building a pre-release version (as indicated by the –CI{0} in your version number). This means you need to select the “Include Prerelease” dropdown in the Package Manager:

    image

    You should see your package with the same version as MyGet is showing.

    At this point you can install your package into a test or client app or wherever you’re using the package. Make changes to it, push the changes to GitHub and magically MyGet will fetch the changes and republish the package for you. Just go into the Updates section in NuGet to see them. Here’s a new package that was created after pushing a change up to GitHub as it appears in the Package Manager GUI in Visual Studio:

    image

    Here you can see we have 1.8.0 installed (from NuGet.org). I changed my package source to MyGet feed and there’s a new version available. It’s labeled as 1.9.0-CI00009 (Prerelease).

    Like I said, you can keep pushing more versions up to GitHub and go nuts until you’re happy with the package and are ready to release.

    Upstream to NuGet

    The last piece in our puzzle is having MyGet push a package up to NuGet. This is a single click operation and while it can be automatic (for example pushing everything from MyGet to NuGet) you might not want that. Users would get the pitchforks out and start camping on your doorstep if you pushed out a new version of your package 10 times in a day.

    Package Sources are the way to get your feed out. By default one for NuGet.org is even created for you, but it’s not configured or enabled. Click on the Package Sources and you’ll see the NuGet.org one. Click on edit (assuming you have a NuGet.org account and API key).

    Enter your information to allow MyGet to talk to NuGet and in the upstream section you’ll see this:

    image

    Check the first option. This allows you to push a package from MyGet to NuGet.

    Finally we’re ready to go but we don’t want version 1.9.0-CI00108 to be going public. So here’s where Semantic Versioning comes into play. Back in MyGet click on Packages on your package and then click the Push Latest button.

    image

    Here’s where the magic happen. MyGet recognizes the “–CI00009” is the prerelease tag in our version. If we leave this in, it’ll push the prerelease up to NuGet. Maybe this is okay but for my use I want to only push up tested packages when I’m ready to release them.

    Clear the Prerelease tag field out. This means that will ignore that tag that’s in your version number and only push the version up using the major.minor.patch (in this case 1.9.0 will be pushed up to NuGet.org).

    Click Push and in a few minutes it’ll be on NuGet with the newest version.

    That’s about it. I know this was long but it was step-by-step and hopefully it should clear up some fuzziness with the process of automatically publishing your GitHub repositories as NuGet packages. As typical it actually took me longer to write this up then to actually do it.

    I encourage you to check out more documentation on MyGet as this just scratches the surface as to what it can do and even in this project there are additional options you can leverage like automatically patching AssemblyInfo.cs in your build, labeling the source when you push from MyGet to NuGet, etc.

    Feel free to leave your comments or questions below and enjoy!

  • Live Kitten Juggling with ASP.NET MVC

    Are you as excited as I am about ASP.NET MVC but want to know more. Or have you been struggling all your life in Web Forms Hell and want to make the leap to MVC and don’t know where to start or who to turn to?

    kitties_small

    Jon Galloway and Christopher Harrison are presenting a fast-paced live virtual session (no travel required, except to get from the couch to the computer which I know is a task but we can do it) that walks you through getting introduced to MVC, Visual Studio, Bootstrap, Controllers, Views, and bears oh my!

    It’s a free-as-in-beer all-day session. If you know some C#, a little HTML, and some JavaScript and want to amp up your game then I encourage you to drop by. The free Microsoft Virtual Academy event runs from 9:00am – 5:00pm PDT on June 23, 2014. Check out this page for more details where you can also register for the event.

    See you there!

  • SPListCollection ContainsList Extension Method

    This is such a simple thing but something every SharePoint developer should have in their toolkit (well, actually, this is something Microsoft should put into the product). The SPFieldCollection has a nice method called ContainsField so you can check for the existence of a field (without throwing an exception if you get the spelling wrong). This is my version of the same method for SharePoint Lists.

     public static class SPListExtensions
    {
    public static bool ContainsList(this SPListCollection lists, string displayName)
    {
    try
    {
    return lists.Cast<SPList>().Any(list => string.Equals(list.Title, displayName, StringComparison.OrdinalIgnoreCase);
    }
    catch (Exception)
    {
    return false;
    }
    }
    }
    Enjoy.

  • Enhancing your SharePoint Team Site Homepage

    A team site can be a boring place. Just a site with some documents, a list or two, maybe a calendar. Here’s a super simple way to make the page a little more interesting looking.

    Your team site might look like this right now, with a calendar on the home page:

    before

    Simple and effective but bland. Also the title just blends into the background doesn’t it?

    Edit the web part and under Advanced settings, set the Title Icon Image URL to the same value as the Calendar Icon Image URL:

    settings

    Now the calendar shows a small icon next to the title and breaks up the page a little.

    after

    Simple but easy to do. By default, the Title icon is blank but IMHO it should be defaulted to the type of list that’s being shown (Calendar, Task List, Document Library, etc.). Like I said, it’s simple but it breaks up the page and also is a visual reminder of what you’re looking at. It also shows where the clickable title is for a list or library that’s been put on a page. When you have a page full of web parts, it’s not immediately obvious where the title is in a sea of text. A little graphic goes a long way for readability.

    You can use any icon for any list but I like using the one suited to the task. Here’s a list of the icons to use for each list/library type:

    List/Library Type Icon
    Custom List /layouts/images/itgen.gif
    Calendar /layouts/images/itevent.png
    Contact List /layouts/images/itcontct.gif
    Site /layouts/images/SharePointFoundation16.png
    Document Library /layouts/images/itdl.png
    Announcements /layouts/images/itann.png
    Discussion Board /layouts/images/itann.png
    Issue Tracker /layouts/images/itissue.png
    Picture Library /layouts/images/itil.png
    Links /layouts/images/itlink.png
    Tasks /layouts/images/ittask.png
    Survey /layouts/images/itsurvey.png

    Enjoy!

  • Virtual Machine Tips for running SharePoint

    Just a few simple Virtual Machine tips when developing in SharePoint

    • My VMs are 40GB in size and pre-allocated. After installing SharePoint, SQL Server, and Visual Studio and all the tools I need I have about 10GB for data which is more than sufficient for most jobs. The pre-allocation helps performance but you need a lot of disk space so keep that in mind when planning your VM.
    • I run my VMs disconnected with their own Domain Controller (for development I usually just run a single VM with DC, SQL, and SharePoint all in one). I reconnect them via a bridge to the host network adapter when I'm at home off my corporate network. This is to get patches and keep things up to date. Running disconnected is nice because you know when things fail and why. Got a rogue web part that's behaving strangely? Put it in your VM and take a look at it to make sure it's not relying on some external service (which may be throwing proxy errors or something from your corporate network)
    • I rely on source control to store my code and only pull down copies of current projects when I'm ready to work on something and keep things fresh with mulitple check-ins per day. With VMWare the nice thing is that I can mount the VM as a disk image in case I need to pull something off (without having to fire up the VM). Having a source control system like GIT or Mercurial instead of Subversion or VSS will let you do local check-ins then you can sync when you're done at the end of the day.
    • VMs on the local drive (if you're running a SSD) are waaaaaaaaaaay faster than on an external drive. If you have to use an external drive for your VMs (I've since stopped doing this with the increased size of SSDs these days) then go with eSATA for the best performance (although some people will argue USB 3.0 is faster). Pre-allocating the VM on an external drive will help with performance as well.
    • Give your VM lots of memory. Any SharePoint developer must be running at least 8GB on their host machine. Give your VM 4-5 GB. No watching movies while you work, defer that to another machine. For SharePoint 2013 you really need to run 16GB on your host machine and give your VMs 8-12 GB of RAM.
    • Copying large files into a VM (like an installer) then deleting it will cause fragmentation that you might not get back during regular usage. Make sure you use your virtualization tools to defragment your VMs on a regular basis.
    • A really great tool to keep your VMs under control size wise is SpaceSniffer. It visually shows you where things are gobbling up space in the OS so you can pinpoint things that you don't need and zap 'em! Get it. It's free!

    That's it for now. Just a few simple tips that might help out. Happy developing!

  • ASP.NET Training Videos Delivered via SharePoint

    Recently Scott Hanselman posted on his blog an ASP.NET Jump Start session they had which featured 9 videos (over 8 hours of content) on developing apps with ASP.NET. This is a great resource and I wanted to share it with the rest of my team. Problem is that a) the team generally doesn’t have access to video content on the web as it’s generally blocked by proxy b) streaming an hour video over the Internet might be okay for one but not for an entire team and c) there must be a better way to share this other than passing out links to Scott’s blog or the Channel 9 site.

    We have a team site in SharePoint so I thought this would be a great opportunity to share the information that way. The problem was that even at medium resolution the files are just too big to host inside of SharePoint.

    Sidebar. There have been a lot of discussions about “Large file support” in SharePoint 2010 (and beyond) and that’s great but for me the bottom line is that extremely large files (over the default 50MB in size) just isn’t meant for an Intranet. I can hear the arguments now about it but a few things to consider with large files (specifically media files like videos). Uploading a 100MB file to the server means 100MB of memory gets gobbled up by the w3wp.exe process (the process attached to the Application Pool running your site) during the entire time the file is being uploaded. LANs are fast but even a 100MB file only gets uploaded at a certain speed (regardless of how big your pipe is). Also uploading the video commits the user to that web front end (usually pegging the server or process) so your load balancing is shot. In short, many people bump up the maximum size of SharePoint’s default of 50MB without taking any of these things into consideration then wonder why their amazing Intranet site is running slow (and usually they toss more memory on the front-ends thinking it will help). Basically 50MB should be the limit for files on any web application when users are uploading.

    In any case, an option is to specify the files via UNC paths which means that a) I can just use the Windows Desktop top copy the files so no size limitations and b) I can address the files via the file:// protocol. This works much for most Intranets and large files and should be considered over stuffing a file into SharePoint (regardless of how you get it in). Remember that a 100MB file in SharePoint generally takes up at least 150MB of space (and if the file is versioned, eek! just watch your content database explode in size!).

    So my first step was to download the files and put them onto a file share. Simple enough. 9 files. I grabbed the medium size files but you can get the HD ones or whatever you want (I just didn’t want to wait around for 500MB per file to download with the high quality WMV files). Medium quality is good enough for training as you can clearly see the code in the IDE and not be annoyed by pixel artifacts on the playback.

    Now that I had my 9 videos of content on the corporate LAN it was time to set something up to display them. You can get way fancier than I did here with some jQuery, doing some Client Object Model code to write out a video carousel but this is a simple solution that required no code (and I do mean absolutely zero code) and a few minutes of time. In fact it took longer to copy the files than it did to setup the list.

    First create a Custom List on the site you want to server your video catalog up from. Then I added three fields (in addition to the default Title field):

    1. Video. This was set to Hyperlink field that would be the UNC path to the video itself on the file share.
    2. Thumbnail. This was a Hyperlink field formatted as a picture and would offer up a snapshot of what the user was going to see.
    3. Description. A multiline field set to Text only that would hold a brief description of the video.

    Here’s the Edit form for a video item:

    • The title is whatever you want (it’s not used for the catalog)
    • The Video is a hyperlink to the file on the file share. This will take the form of “file://” instead of “http://” and point to your UNC path to the file. Put the full title (or whatever the user is going to see to click on) in the description field. With Hyperlink fields if you leave the description field blank it gets automatically filled in with the full link (which isn’t very user friendly).
    • The Thumbnail is a hyperlink to an image. You can choose to make your own (if your content is your own). I cheated here and just grabbed the image directly off of Scott’s blog (which is up on some Microsoft content delivery network location). As this field is formatted as a Picture it’ll just display the image so make sure it points to an image file SharePoint recognizes (JPEG is probably preferred here).
    • The Description field is just copied straight off the blog. Again, change this to whatever you want so users know what the video is about.

    Once you populate the list with the videos you almost ready to go. Here’s the default view of the list:

    This is okay but not very user friendly for viewing videos. Users might click on the Title field which would open up the List Item instead of launching the video. So instead either create a new view or modify the default one. If you create a new view you might want to set it as a new default so when a user visits the list they see the right view.

    In your new view we’ll set a few options:

    • Set the first three columns to be Thumbnail, Video, and Description (in this order). This is to create the catalog view of the world so you might want another view for editing content (in case you’re adding something or want to update a value).
    • Turn off Tabular View as we don’t need it here
    • Under Style choose “Boxed, no labels”

    Now here’s the updated view in the browser:

    Pretty slick and only took 5 minutes to build the view. Users click on the title and the video launches in Windows Media Player (or whatever player is associated with your video file format you’re pointing to).

    Note that this posts talks about a specific set of files for a solution but the video content is up to you. If you have some high quality/large format audio or video files in your organization and want to surface them up in a catalog this solution might work for you. It’s not about the content, it’s about serving up that content.

    Enjoy!

  • Convention over Configuration with MVC and Autofac

    One of the key things to wrap your head around when doing good software development using frameworks like ASP.NET MVC is the idea of convention over configuration (or coding by convention).

    The idea is that rather than messing around with configuration files about where to find things, how to register IoC containers, etc. that we used to do, you follow a convention, a way of doing things. The example normally expressed is a class in your model called “Sale” and a database named “Sales”. If you don’t do anything that’s how the system will work but if you decide to change the name of the database to “Products_Sold” then you need some kind of configuration to tell the system how to find the backend database. Otherwise it can naturally find it based on the naming strategy of your domain.

    MVC does this by default. When you create a controller named “Home” the class is HomeController and the views of the HomeController are found in /Views/Home for your project. When dealing with IoC containers there’s the task of registering your types to resolve correct. So let’s take a step back and take a look at a project with several repositories in it (a repository here being some kind of abstraction over your data store).

    Here we have under our Models: Customer, Invoice, and Product with their respective classes, repositories, and interfaces:

    image

    This might be how your project is typically setup. I want to inject the dependencies on my repositories into my controller (via my IoC system) like this:

       1:  public class HomeController : Controller 
       2:  { 
       3:      private readonly ICustomerRepository _customerRepository; 
       4:      private readonly IInvoiceRepository _invoiceRepository; 
       5:      private readonly IProductRepository _productRepository;
       6:   
       7:      public HomeController(
       8:  ICustomerRepository customerRepository,
       9:  IInvoiceRepository invoiceRepository, 
      10:  IProductRepository productRepository) 
      11:      { 
      12:          _customerRepository = customerRepository; 
      13:          _invoiceRepository = invoiceRepository; 
      14:          _productRepository = productRepository; 
      15:      }
      16:   
      17:      // 
      18:      // GET: /Home/ 
      19:      public ActionResult Index() 
      20:      { 
      21:          return View(); 
      22:      } 
      23:  }

    Then somewhere in my controller I’ll use the various repositories to fetch information and present it to the user (or write back values gathered from the user). How do my IoC know how to resolve an ICustomerRepository object?

    Here’s how I have my IoC engine setup for this sample using Autofac. You can use any IoC engine you want but I find Autofac works well with MVC. First in Global.asax.cs I just follow the same pattern that the default projects setup and add a new static class called ContainerConfig.RegisterContainer()

       1:  public class MvcApplication : System.Web.HttpApplication 
       2:  { 
       3:      protected void Application_Start() 
       4:      { 
       5:          AreaRegistration.RegisterAllAreas();
       6:   
       7:          WebApiConfig.Register(GlobalConfiguration.Configuration); 
       8:          FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
       9:          RouteConfig.RegisterRoutes(RouteTable.Routes); 
      10:          BundleConfig.RegisterBundles(BundleTable.Bundles); 
      11:          ContainerConfig.RegisterContainer(); 
      12:      } 
      13:  }

    Next is setting up Autofac. First add the Autofac MVC4 Integration package either through the NuGet UI or the Package Manager Console:

    PM> Install-Package Autofac.Mvc4

    Next here’s my new ContainerConfig class I created which will register all the types I need:

       1:  public class ContainerConfig 
       2:  { 
       3:      public static void RegisterContainer() 
       4:      { 
       5:          var builder = new ContainerBuilder(); 
       6:          builder.RegisterControllers(Assembly.GetExecutingAssembly()); 
       7:          builder.RegisterType<CustomerRepository>().As<ICustomerRepository>(); 
       8:          builder.RegisterType<InvoiceRepository>().As<IInvoiceRepository>(); 
       9:          builder.RegisterType<ProductRepository>().As<IProductRepository>(); 
      10:          var container = builder.Build(); 
      11:          DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
      12:      }
      13:   
      14:  }

    What’s going on here:

    Line 5 Create a new ContainerBuilder
    Line 6 Register all the controllers using the assembly object
    Line 7-9 Register each repository
    Line 10 Build the container
    Line 11 Set the default resolver to use Autofac

    Pretty straight forward but here are the issues with this approach:

    1. I have to keep going back to my ContainerConfig class adding new repositories as the system evolves. This means not only do I have to add the classes/interfaces to my system, I also have to remember to do this configuration step. New developers on the project might not remember this and the system will blow up when it can’t figure out how to resolve INewRepository
    2. I have to pull in a new namespace (assuming I follow the practice of namespace = folder structure) into the ContainerConfig class and whatever controller I add the new repository to.
    3. Repositories are scattered all over my solution (and in a big solution this can get a little ugly)

    A little messy. We can do better with convention over configuration.

    First step is to move all of your repositories into a new folder called Repositories. With ReSharper you can just use F6 to do this and it’ll automatically move and fix the namespaces for you, otherwise use whatever add-in your want or move it manually. This includes both the classes and interfaces. Here’s what our solution looks like after the move:

    image

    Pretty simple here but how does this affect our code? Really minimal. In the controller(s) that you’re injecting the repository into, you just have to remove all the old namespaces and replace it with one (whatever namespace your repositories live in).

    The other change is how you register your ContainerConfig. Here’s the updated version:

       1:  public class ContainerConfig 
       2:  { 
       3:      public static void RegisterContainer() 
       4:      { 
       5:          var builder = new ContainerBuilder(); 
       6:          builder.RegisterControllers(Assembly.GetExecutingAssembly()); 
       7:          builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
       8:              .Where(x => x.Namespace.EndsWith(".Repositories"))
       9:              .AsImplementedInterfaces(); 
      10:          var container = builder.Build(); 
      11:          DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
      12:      } 
      13:  }

    Note that a) we only have one line to register all the repositories now and b) the namespace dependency we had in our file is now gone.

    The call to RegisterAssemblyTypes above using the convention of looking for any class/interface in a namespace that ends with “.Repositories” and then simply registers them all.

    So for the new developer on the project the instructions to them are to just create new repository classes and interfaces in the Repositories folder. That’s it. No configuration, no mess.

    Hope that helps!

  • Defaulting Values in a Multi-Lookup Form in SharePoint

    This was a question asked on the MSDN Forums but I thought it was worthy of a blog post as I could get more in depth with the explanation and show some pretty pictures (plus the fact I’ve never done it so thought it would be fun).

    The problem was a user wanted to default multiple values in a lookup field in SharePoint. First problem, there are no defaults in a lookup field. Second problem, how do you do default multiple values?

    First we’ll start with the setup. Create yourself a list which will hold the lookup values. In this case it’s a list of country names but it can be anything you want. Just a custom list with the Title field is enough.

    image

    Now we need a list with a lookup column to select our countries from. Create another custom list and add a column to it that looks something like this. Here’s the name and type:

    image

    And here’s the additional column settings where we get our information from (MultiLookupDefaultSpikeSource is the name of the list we created to hold our values)

    image

    Here’s what our form looks like when we add a new item:

    image

    Thinking about the problem I first though we could manipulate the form in SharePoint Designer but realized that the Form Web Part is going to retrieve all of our values from the list, defaults, etc. and really what we need to do is manipulate the list at runtime in the DOM.

    It’s jQuery to the RESCUE!

    First we take a look at the original state of the form to find our list boxes. Here’s the snippet we’re interested in, the first listbox:

     <select   
     name="ctl00$m$g_478fe6d2_8fdb_48e8_be57_7739de1c3b8f$ctl00$ctl05$ctl01$ctl00$ctl00$ctl04$ctl00$ctl00$SelectCandidate"   
     title="Country possible values"   
     id="ctl00_m_g_478fe6d2_8fdb_48e8_be57_7739de1c3b8f_ctl00_ctl05_ctl01_ctl00_ctl00_ctl04_ctl00_ctl00_SelectCandidate"   
     style="width: 143px; height: 125px; overflow: scroll;"   
     ondblclick="GipAddSelectedItems(ctl00_m_g_478fe6d2_8fdb_48e8_be57_7739de1c3b8f_ctl00_ctl05_ctl01_ctl00_ctl00_ctl04_ctl00_ctl00_MultiLookupPicker_m); return false"   
     onchange="GipSelectCandidateItems(ctl00_m_g_478fe6d2_8fdb_48e8_be57_7739de1c3b8f_ctl00_ctl05_ctl01_ctl00_ctl00_ctl04_ctl00_ctl00_MultiLookupPicker_m);"   
     multiple="multiple">   
     <OPTION title=Africa selected value=5>Africa</OPTION>   
     <OPTION title=Asia value=1>Asia</OPTION>   
     <OPTION title=Europe value=3>Europe</OPTION>   
     <OPTION title=India value=4>India</OPTION>   
     <OPTION title=Ireland value=6>Ireland</OPTION>   
     <OPTION title=Singapore value=2>Singapore</OPTION>   
     </select>  
    

    We can see that it has an ID that ends in “_SelectCandidate” so we’ll use this for selection.

    Another part of the puzzle is a hidden set of fields that store the actual values used in the list. There are three of them and they’re well documented in a blog post here by Marc Anderson on SharePoint Magazine. In it he talks about multiselect columns and breaks down the three hidden fields used (the current set of values, the complete set of values, and the default values).

    The second listbox looks like this:

     <select   
     name="ctl00$m$g_478fe6d2_8fdb_48e8_be57_7739de1c3b8f$ctl00$ctl05$ctl01$ctl00$ctl00$ctl04$ctl00$ctl00$SelectResult"   
     title="Country selected values"   
     id="ctl00_m_g_478fe6d2_8fdb_48e8_be57_7739de1c3b8f_ctl00_ctl05_ctl01_ctl00_ctl00_ctl04_ctl00_ctl00_SelectResult"   
     style="width: 143px; height: 125px; overflow: scroll;"   
     ondblclick="GipRemoveSelectedItems(ctl00_m_g_478fe6d2_8fdb_48e8_be57_7739de1c3b8f_ctl00_ctl05_ctl01_ctl00_ctl00_ctl04_ctl00_ctl00_MultiLookupPicker_m); return false" \   
     onchange="GipSelectResultItems(ctl00_m_g_478fe6d2_8fdb_48e8_be57_7739de1c3b8f_ctl00_ctl05_ctl01_ctl00_ctl00_ctl04_ctl00_ctl00_MultiLookupPicker_m);"   
     multiple="multiple">  
    

    Easy enough. It has an ID that contains “_SelectResult”.

    Now a quick jQuery primer when selecting items:

    • $("[id='foo']"); // id equals 'foo'
    • $("[id!='foo']") // id does not equal 'foo'
    • $("[id^='foo']") // id starts with 'foo'
    • $("[id$='foo']") // id ends with 'foo'
    • $("[id*='foo']") // id contains 'foo'

    Simple. We want to find the control that ends with “_SelectCandidate” and remove some items, then find the control that ends with “_SelectResult” and append our selected items.

    So a few lines of heavily commented JavaScript:

     $(document).ready(function(){  
       // define the items to add to the results (i.e already selected) this the visual part only   
       var $resultOptions = "<OPTION title=Africa value=5>Africa</OPTION><OPTION title=India value=4>India</OPTION><OPTION title=Ireland value=6>Ireland</OPTION>";   
       // this is the list of initial items (matching the ones above) that are used when the item is saved   
       var $resultSpOptions = "5|tAfrica|t4|tIndia|t6|tIreland";   
       // find the possible values control   
       var possibleValues = $("[id$='_SelectCandidate']");  
       // remove 1st option (Africa)   
       $("[id$='_SelectCandidate'] option:eq(0)").remove();  
       // remove 3rd option (India)   
       $("[id$='_SelectCandidate'] option:eq(2)").remove();  
       // remove 3rd option (Ireland)   
       $("[id$='_SelectCandidate'] option:eq(2)").remove();  
       // set selected value to asia (value 1)   
       possibleValues.val(1)  
       // append the new options to our results (this updates the display only of the second list box)   
       $("[id$='_SelectResult']").append($resultOptions);  
       // append the new options to our hidden field (this sets the values into the list item when saving)   
       $("[id$='MultiLookupPicker']").val($resultSpOptions);   
     });  
    

    SharePoint 2010 supports editing NewForm.aspx (and the other out-of-the-box forms) in the browser. One option is to modify the list and under advanced settings you can disable “Launch forms in a dialog”. This will launch the form like a regular web page. However that’s 3 or 4 steps and you have to go back and change it when you’re done.

    Instead just visit the new form directly:

    http://sitename/listname/NewForm.aspx

    From this page select Site Actions | Edit Page. Now you can add a Content Editor Web Part to the page. When adding JavaScript I point the Content Link to the .js file (that I upload somewhere like Style Library or the Assets library if you have one) rather than trying to put JavaScript into the Content Editor Web Part. This way a) I can edit the JavaScript outside of the page by loading it up in SharePoint Designer or even upload a new .js file to the library and b) I can debug the JavaScript independently of the NewForm.aspx page (or whatever page I’m adding the .js file to)

    The result:

    image

    When you save the record, the three default options are saved as well (this was set by the JavaScript).

    Hope that helps!

  • Where tips in LINQ

    These might be old but as I was going through doing some code reviews and optimizations I thought I would share with the rest of the class.

    Count() > 0 vs. Any

    This is a bit of heated debate but as you dive in the LINQ world you'll start seeing simpler ways to write things. LINQ itself gets you away from writing loops for example (sometimes). One thing I notice in code are things like this:

    if(entity.Where(some condition).Count() > 0)

    When you could just write this instead:

    if(entity.Any(some condition))

    For me, writing *less* code is *more* important. It's a cornerstone in refactoring. Making your code more readable, more succinct. If you can scan code quicker while troubleshooting a problem or trying to figure out where to add an enhancement, all the better.

    Donn Felker wrote  about the Count() vs. Any() discussion here back in 2009 and it was discussed on StackOverflow here in case you're wondering if Any() is more performant than Count() (it generally is). So my advice is use Any() to make your code potentially easier to read unless there's a performance problem.

    Another simple tip for code reduction is this one.

    var x = entity.Where(some condition).FirstOrDefault();

    Becomes:

    var x = entity.FirstOrDefault(some condition);

    I know it's simple but again it's about readability. The better you can scan someone elses new code you've never seen before is less time stumbling over the syntax and more about what the intention is.

    Yes, these tips are old but you would be surprised seeing new developers write new code with them and wonder why?

  • Windows 8 and the Lethbridge Technology User Group

    Join me and 83,517 screaming nerds (everyone in the city is attending and a geek right?) on Thursday February 21st from 3-5pm to talk about building Metro style apps for WIndows 8. Here's what we'll be covering.

    Windows 8 Platform for Metro Style Apps

    Windows 8 is Windows re-imagined. Join this session to learn about the new platform for building Metro style apps. Get an understanding of the platform design tenets, the programming language choices and the integration points with the operating system and across Metro style apps

    Everything Web Developers Must know to build Metro Style Apps

    Learn how you can use your web skills to build Windows 8 Metro style apps using HTML5, CSS3 and JavaScript. In this session you’ll discover how to harness the rich capabilities of Windows 8 through JavaScript and the Windows Runtime. You will learn about navigation, user experience patterns and controls, inherent async design and the seamless integration with the operating system that will let you create great Metro style apps.

    I promise fun times, chaos monkeys, and live kitten juggling as per my usual presentations.