SideWaffle–standardowe szablony dla Visual Studio

Zanim przejdziemy do tworzenia własnych szablonów dla ASP.NET MVC scaffolding, warto zainstalować SideWaffle. To nic innego jak zestaw szablonów i projektów. Link:
http://sidewaffle.com/

Pełną listę dostępnych szablonów można zobaczyć na stronie sidewaffle. Głównie są to szablony związane z web, szczególnie z AngularJS. Po zainstalowaniu zobaczymy nowe typy projektów jak i szablony dla nowych plików. Na przykład, w aplikacji Web mamy:

image

Wybierając szablon requirejs, zostanie wygenerowany szkielet modułu:

require(["helper/util"], function (util) {
    //This function is called when scripts/helper/util.js is loaded.
    //If util.js calls define(), then this function is not fired until
    //util's dependencies have loaded, and the util argument will hold
    //the module value for "helper/util".
});

Naprawdę przydatne, bo w końcu pisanie tego ręcznie dla każdego modułu jest monotonne. Ostatnio na blogu pisałem o knockout.js. Również i dla tej biblioteki istnieje szablon:

//Template taken from http://knockoutjs.com/documentation/custom-bindings.html
ko.bindingHandlers['binding1'] = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        // This will be called when the binding is first applied to an element
        // Set up any initial state, event handlers, etc. here
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        // This will be called once when the binding is first applied to an element,
        // and again whenever the associated observable changes value.
        // Update the DOM element based on the supplied values here.
    }
};

Najwięcej chyba szablonów jest dostępnych dla AngularJS. Przykład (AngularJS Module):

(function () {
    'use strict';

    var id = 'app1';

    // TODO: Inject modules as needed.
    var app1 = angular.module('app1', [
        // Angular modules 
        'ngAnimate',        // animations
        'ngRoute'           // routing

        // Custom modules 

        // 3rd Party Modules
        
    ]);

    // Execute bootstrapping code and any dependencies.
    // TODO: inject services as needed.
    app1.run(['$q', '$rootScope',
        function ($q, $rootScope) {

        }]);
})();

Oczywiście, mamy również szkielety dla kodu c#, a nie tylko JavaScript. Zobaczmy co wygeneruje nUnit Fixture:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;

namespace MvcApplication1
{
    [TestFixture]
    public class NUnitFixture1
    {
        [SetUp]
        public void Setup()
        {

        }

        [Test]
        public void Test()
        {
            throw new NotImplementedException();
        }
    }
}

Nawet dla SVG mamy małą pomoc w formie:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="200">
  <rect width="300" height="120" y="20" fill="green"/>
  <rect width="80" height="150" x="20" y="30" fill="red"/>
  <rect width="140" height="80" x="50" y="50" fill="blue"/>
</svg>

Dla programistów Azure, mamy 3 szkielety klas m.in. ułatwiające prace z Azure Table oraz Blob:

image

Przykład (Azure Blob):

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;

namespace WebApplication4.Controllers
{
    public class BlobUploadHelper1
    {
        private string _connectionString;
        private CloudStorageAccount StorageAccount { get; set; }

        public BlobUploadHelper1()
            : this(ConfigurationManager
                .ConnectionStrings["BlobUploadHelper1.ConnectionString"]
                    .ConnectionString)
        {
        }

        public BlobUploadHelper1(string connectionString)
        {
            _connectionString = connectionString;
        }

        public CloudBlobClient GetBlobClient()
        {
            StorageAccount = CloudStorageAccount.Parse(_connectionString);
            return StorageAccount.CreateCloudBlobClient();
        }

        public CloudBlobContainer GetBlobContainer(string containerName,
            BlobContainerPublicAccessType accessType = BlobContainerPublicAccessType.Blob)
        {
            var container = GetBlobClient().GetContainerReference(containerName);
            container.CreateIfNotExists();
            container.SetPermissions(new BlobContainerPermissions
            {
                PublicAccess = accessType
            });
            return container;
        }

        public string UploadFileToBlob(HttpPostedFileBase postedFile, string containerName = "uploads")
        {
            var container = GetBlobContainer(containerName);
            var blob = container.GetBlockBlobReference(Path.GetFileName(postedFile.FileName));
            using (postedFile.InputStream)
            {
                blob.UploadFromStream(postedFile.InputStream);
            }
            return blob.Uri.AbsoluteUri;
        }

        public List<string> GetBlobList(string containerName)
        {
            var container = GetBlobContainer(containerName);
            var ret = container.ListBlobs().Select(x => x.Uri.AbsoluteUri).ToList();
            return ret;
        }
    }
}

Warto zaznaczyć, że SideWaffle to nie tylko nowe typy projektów oraz szablonów, ale również snippet’y. Do dyspozycji mamy m.in. Nancy, WCF Client, Dispose czy Angular. Dispose wygląda następująco:

#region IDisposable Members

/// <summary>
/// Internal variable which checks if Dispose has already been called
/// </summary>
private Boolean disposed;

/// <summary>
/// Releases unmanaged and - optionally - managed resources
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(Boolean disposing)
{
    if (disposed)
    {
        return;
    }

    if (disposing)
    {
        //TODO: Managed cleanup code here, while managed refs still valid
    }
    //TODO: Unmanaged cleanup code here

    disposed = true;
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
    // Call the private Dispose(bool) helper and indicate 
    // that we are explicitly disposing
    this.Dispose(true);

    // Tell the garbage collector that the object doesn't require any
    // cleanup when collected since Dispose was called explicitly.
    GC.SuppressFinalize(this);
}

/// <summary>
/// The destructor for the class.
/// </summary>
~ClassNamePlaceholder() 
{ 
    this.Dispose(false); 
}


#endregion

Z kolei WCF Client:

try
{
  //todo: make calls to the client - should be as small a set of work here as possible
  client.Close();
}
catch (System.ServiceModel.CommunicationException e)
{
  //todo: handle communication exceptions, for example cannot connect to service.
  client.Abort();
}
catch (TimeoutException e)
{
  //todo: handle time outs when connecting, calling and closing
  client.Abort();
}
catch (Exception e)
{
  //todo: handle any other client issue
  client.Abort();
  throw;
}

Co do snippetów… Istnieje jeszcze nawet szablon na własne snippety, bo w końcu każdy z nich zawiera pewne elementy wspólne:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>snippet1</Title>
      <Shortcut>snippet1</Shortcut>
      <Description>A description for snippet1</Description>
      <Author>Microsoft Corporation</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="true">
          <ID>message</ID>
          <ToolTip>The message</ToolTip>
          <Default>Hi there!</Default>
        </Literal>
      </Declarations>
      <Code Language="CSharp"><![CDATA[
            Console.WriteLine("$message$");
        ]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Przedstawione w tym poście szkielety to bardzo mała część z tych, które są dostępne w pakiecie. Oczywiście z większości prawdopodobnie nie będziemy korzystać w tym samym projekcie, ale warto je przejrzeć, aby następnym razem już nie marnować czasu na pisanie powtarzalnych części kodu.

2 thoughts on “SideWaffle–standardowe szablony dla Visual Studio”

  1. Dzięki za odpowiedź pod którymś postem na temat książki do optymalizacji C#. A do nauki T-SQL coś polecisz?

Leave a Reply

Your email address will not be published.