Click here to Skip to main content
Click here to Skip to main content

Knit - A Visual Studio Add-In

, 30 Dec 2007
Rate this:
Please Sign up or sign in to vote.
Knit is a Visual Studio add-in tool that allows a developer to apply multi-step patterns to solution and assembly meta-data.

Introduction

Knit is a Visual Studio add-in tool that allows a developer to apply multi-step patterns to solution and assembly meta-data.

Although originally created to stitch projects together into SharePoint 2007 solutions, Knit is flexible and expandable enough to handle almost any post build meta-data processing.

The meta-data of Visual Studio solutions, projects, and project files are exposed as XML to a knitting pattern via a “Skein” file. In addition, each project in the Skein file also contains its .NET reflected meta-data. The Skein file is available to each pattern step, including the powerful “Stitch” step that applies an XSLT transform.

New patterns are easily created in XML, and several powerful step processes are built-in to allow the developer complete autonomy to create post-build knitting patterns.

Background

The whole concept of distributing SharePoint Web Parts and other customizations has been greatly simplified, by the addition of the solution CAB file. The solution CAB file contains all the necessary files, including a manifest.xml file which defines how and where SharePoint will install each component. Installing a packaged solution on a SharePoint site is just a single command line instruction using the stsadm.exe tool supplied. The structure of the CAB file and the manifest.xml file is fairly straightforward, and is better explained by the CodeProject article: Fundamentals of SharePoint Web Parts (Part II: Deployment Methods) by _alank, and by the Microsoft MSDN article: Solutions Overview.

SharePoint solution files are not to difficult to create when your Visual Studio solution is relatively simple, containing, for instance, a single project with one or two Web Parts. Keeping the solution and manifest.xml file in sync with a VS solution that spans several projects, including custom fields, .ASCX user controls, .ASPX pages, and other SharePoint template files can be trying even for the most dedicated developer. Luckily, most of the information needed to create these solutions is contained in the structure and meta-data inside Visual Studio solutions, the projects, and the assemblies. Why not create a tool to access the meta-data and make it more accessible for packaging?

Since the complexity of the SharePoint solutions I was creating varied from assignment to assignment, I needed a tool that could be updated and extended relatively easily; a way to expose all the meta-data of Visual Studio and make it easy to manipulate. Using the Visual Studio add-in technology (see the Microsoft MSDN article Creating Add-ins and Wizards), I created the Knit add-in. At the time of this article, the source code for the Knit add-in remained copyrighted by Hitachi Consulting; they have however, kindly agreed to allow the binaries of the tool to be distributed as part of this article. The main thrust of this article is to explain the use of Knit, how it exposes Visual Studio meta-data, and how to create patterns, with a specific example for packaging SharePoint 2007 solutions.

Installing Knit

Download and install the Knit binaries. Knit requires that Visual Studio 2005 or 2008 be installed. Download and unzip the Knit.zip file, and execute Setup.exe. The setup wizard has three options:

  • Install Knit for Visual Studio 2005
  • Install Knit for Visual Studio 2008
  • Install Knit Pattern Examples

Getting started with Knit

Once installed, Knit should appear at the top of the Tools menu in Visual Studio, the next time that Visual Studio is launched. Knit can be executed by either clicking on the "Knit" menu item or by executing the Visual Studio command "knit".

Visual Studio Tool Menu

The Knit dialog box will be displayed, allowing you to select a pattern to start knitting with.

Knit Dialog

When Knit executes, it produces output to an output pane labeled "knit".

Knit Output Pane

Executing Knit as a Visual Studio command requires that the label of the pattern be specified as its argument. For example: Knit Share Point 2007 - Solution. Executing Knit as a command does not invoke the Knit dialog box.

Knit architecture

The following diagrams depict how Knit examines meta-data and applies pattern steps to product output.

Knitting machine: Pass 1

The first pass of the knitting machine,examines the Visual Solution meta-data and processes each project and each project file. For each project that produces an assembly file, if the assembly file exists, it is opened, and .NET Reflection is used to extract the assembly meta-data. All meta-data is combined with the user inputted options, converted to XML tags, and added to the Skein document.

Knit Pass 1

Knitting machine: Pass 2

The knitting machine then applies each step of the selected pattern, using the Skein document of Pass 1 as input. The step executes, resulting in one or more output files being created in Visual Studio or in the solution directory.

Knit Pass 2

Finally, if the user selected to produce a skein file, the Skein document is output as a file.

The Skein file

The heart of the knitting machine is the "Skein" file. The Skein file is an XML representation of the entire Visual Studio project as well as all selected knitting options and the assembly meta-data. In short, it contains everything about your solution, except the code itself! As the pattern is executed, each step appends information to the Skein file, making it available to the next step of the pattern; an example of this can be seen at the bottom of the example, between the <outputs>...<outputs/> tags.

Below is an abbreviated example of a Skein file for a simple solution (note that much of the file has been abbreviated using ellipses "...", including file paths, to conserve screen space):

<skein xmlns="http://hitachiconsulting.com/namespaces/visualstudio/knit/skein">
  <options>
    <option name="AutoSaveFiles">true</option>
    <option name="CreateSkeinFile">true</option>
    <option name="SolutionID">ac468818-e45b-4e17-b453-b4b437b273cf</option>
    <option name="GenerateWebPartFiles">true</option>
  </options>
  <solution name="Hitachi.VisualStudio.Knit.UnitTest" 
               path="C:\Users\...\VisualStudio\Knit\UnitTest">
    ...
    <project name="UnitTest" unique-name="UnitTest\UnitTest.csproj">
      <assembly name="Hitachi.Sharepoint.SolutionBuilder.UnitTest" 
            full-name="Hitachi.Sharepoint.SolutionBuilder.UnitTest, 
                       Version=1.0.0.0, Culture=neutral, 
                       PublicKeyToken=dda93a23bface736" 
            location="C:\Users\...\UnitTest\bin\Debug\Hitachi.
                      Sharepoint.SolutionBuilder.UnitTest.dll" 
            version="1.0.0.0" culture="neutral" 
            public-key-token="dda93a23bface736">
        <type name="TestWebPart" 
             full-name="Hitachi.Sharepoint.SolutionBuilder.UnitTest.TestWebPart" 
             namespace="Hitachi.Sharepoint.SolutionBuilder.UnitTest" 
             base-type="System.Web.UI.WebControls.WebParts.WebPart">
          <attribute name="Public" type="System.Reflection.TypeAttributes" />
          ...
          <attribute name="Bindable" 
             type="System.ComponentModel.BindableAttribute" 
             Bindable="True" Direction="OneWay" />
          <member-property name="Title" property-type="System.String">
            <attribute name="WebBrowsable" 
               type="System.Web.UI.WebControls.WebParts.WebBrowsableAttribute" 
               Browsable="True" />
            <attribute name="Personalizable" 
               type="System.Web.UI.WebControls.WebParts.PersonalizableAttribute" 
        IsPersonalizable="True" 
        IsSensitive="False" Scope="User" />
            <attribute name="DefaultValue" 
               type="System.ComponentModel.DefaultValueAttribute" 
               Value="Knit Test Web Part" />
          </member-property>
       ...
          <member-property name="Description" property-type="System.String">
           ...
          </member-property>
          <member-method name="DoSomeStuff" return-type="System.Void">
            <attribute name="FamANDAssem" type="System.Reflection.MethodAttributes" />
            <attribute name="Family" type="System.Reflection.MethodAttributes" />
            <attribute name="Public" type="System.Reflection.MethodAttributes" />
            <attribute name="HideBySig" type="System.Reflection.MethodAttributes" />
            <parameters>
              <parameter name="a" type="System.Int32" />
              <parameter name="b" type="System.String" />
              <parameter name="c" type="System.Boolean" />
            </parameters>
          </member-method>
          <member-method name="Render" return-type="System.Void">
            ...
          </member-method>
        </type>
      </assembly>
      <folder name="_layouts">
        <folder name="HitachiConsulting">
          <folder name="KnowledgeManagement">
            <folder name="Rating">
              <file name="Comments.aspx">
                <properties>
                  <property name="Extension">.aspx</property>
                  <property name="FileName">Comments.aspx</property>
                  ...
                  <property name="DateCreated">11/15/2007 4:16:30 PM</property>
                  <property name="LocalPath">C:\Users\...\Comments.aspx</property>
                </properties>
              </file>
              <folder name="Images">
                <folder name="Rating">
                  <file name="0.png">
                    ...
                  </file>
                  ...
                  <file name="none.png">
                    ...
                  </file>
                  <properties>
                    ...
                  </properties>
                </folder>
                <properties>
                  ...
                </properties>
              </folder>
        ...
            </folder>
        ...
          </folder>
  </solution>
  <outputs>
    <step-outputs from-step="Step_0">
      <output name="disposition">continue</output>
    </step-outputs>
    <step-outputs from-step="webparts">
      <output name="disposition">manifest</output>
    </step-outputs>
    <step-outputs from-step="manifest">
      <output name="file-name">C:\Users\...\manifest.xml</output>
      <output name="disposition">fail</output>
    </step-outputs>
  </outputs>
</skein>

The SharePoint-SolutionBuilder Pattern

The SharePoint Solution-Builder Pattern included with the Knit tool is designed to create a solution CAB file, a manifest.xml file, and all .webpart definition files directly from the meta-data of the Visual Studio Solution and of the .NET assembly files.

<?xml version="1.0" encoding="utf-8" ?>
<pattern xmlns="http://hitachiconsulting.com/namespaces/visualstudio/knit/pattern" 
         name="SharePoint-SolutionBuilder" label="Share Point 2007 - Solution"> 
    <description> Generates a complete Share Point 2007 Solution, 
                  including all web part definition files. </description> 
    <options> 
        <option type="guid" required="true" persist="true" 
                 name="SolutionID" label="Share Point Solution GUID"> 
            <description>Uniquely identifies a Share Point solution.</description> 
        </option> 
        <option type="check-box" persist="true" name="GenerateWebPartFiles" 
                label="Generate .webpart files" default-value="true">
             <description>Generate .webpart files by scanning each 
                assembly for web parts Note that the values 
                of properties are extracted from the [DefaultValue] attribute. 
                To supply a value for Title and Description, override the base property and 
                supply a [DefaultValue] attribute. 
            </description> 
        </option> 
    </options> 
    <steps> 
        <if expression="/ns:skein/ns:options/ns:option[@name='GenerateWebPartFiles']='true'" 
           on-false="no-webparts"/> 
        <stitch name="webparts" label="generating webpart file(s)" 
            uri="$(PatternPath)\Transforms\webparts.xslt" 
            on-success="manifest" 
            on-failure="manifest"/> 
        <message name="no-webparts" 
          text="Web Part definition file generation disabled by user" popup="false"/> 
        <stitch name="manifest" label="generating manifest file" 
            uri="$(PatternPath)\Transforms\manifest.xslt" 
            output-path="$(SolutionPath)\manifest.xml"/> 
        <stitch name="cabinet-definition" label="generating cabinet definition file" 
            uri="$(PatternPath)\Transforms\cabinetDefinition.xslt" 
            output-path="$(SolutionPath)\wsp_structure.ddf"/> 
        <execute name="makecab" window="Normal" label="generating cabinet file" 
            command="MAKECAB.EXE" directory="$(SolutionPath)" 
            arguments="/f "$(SolutionPath)\wsp_structure.ddf""/> 
        <message text="Sharepoint-SolutionBuilder knitted!" popup="true"/> 
    </steps> 
</pattern>

Note that the key steps in this pattern are the <stitch> steps. Each stitch step uses the Skein file as input, applying an XSLT transform to produce an output file. For more information on the XLST style sheet standards, visit w3.org for the article: XSL Transforms (XSLT) Version 1.0. I've also found that w3schools.com has a fairly good XSLT tutorial for developers just starting out.

The first stitch step, labeled "webparts", applies the XSLT file "webparts.xslt" to scan the Skein file for any assembly type that has properties using the SharePoint [WebBrowsable] attribute. Each type found with a [WebBrowable] property is used to generate a .webpart file for the solution.

The second stitch step, labeled "manifest", applies the XSLT file "manifest.xslt" to scan the Skein file and create a SharePoint solution manifest file (manifest.xml).

The third and final stitch step, labeled "cabinet-definition", creates the cabinet definition (.ddf) file that is used as input to the makecab step.

For additional details on how to create a pattern definition, including details on creating custom steps, please refer to the Knit user's guide that is installed as part of the Knit Add-In download.

Using the SharePoint-SolutionBuilder Pattern

The SharePoint-SoutionBuilder Pattern comes with the installed version of Knit. To apply the SharePoint-SoutionBuilder knitting pattern to your solution, select "Knit" from the Tools menu and select the SharePoint 2007 solution from the pattern selection drop-down list. The first time you select the pattern, you will need to either supply or generate a GUID for the solution ID from the Knit dialog box. Knit expects a little structure to your SharePoint solution before it can generate a valid solution file. If you are including files to be placed in the shared TEMPLATE directory of SharePoint, you need to structure your project as follows:

  • Solution
    • Project (or Web)
      • TEMPLATE
        • template-folder (optional)
          • template-folder (optional)
            • file (with a build action set to "content")
            • file (with a build action set to "content")

Any file with a build action property of "content" under the "TEMPLATE" folder will be copied into the appropriate place in the SharePoint common TEMPLATE folder when the solution is installed. A good example of this is to create a project that installs a SharePoint custom field type (see the Microsoft MSDN article on custom field types for more info). To install the custom field definition file, set up your solution structure as follows:

  • Solution
    • Project (or Web)
      • TEMPLATE
        • Xml
          • fldtypes_myfield.xml (with a build action set to "content")

To simplify referencing resources located with the SharePoint common URL, http://{share point site}/_layouts/{resource-path}, the pattern also expects to find resources with the project structure, as follows:

  • Solution
    • Project (or Web)
      • _layouts
        • resource-folder (optional)
          • resource-folder (optional)
            • file (with a build action set to "content")
            • file (with a build action set to "content")

Download the sample Web Part project to see an example of these structures.

Points of interest

The Knit tool does a great job of exposing all of the meta-data Visual Studio maintains about a solution. I envision expanding this tool in the future to include a number of different structure and assembly inspection patterns.

History

  • December 30, 2007 - First version.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)

About the Author

AGD-H
Architect Hitachi Consulting
United States United States
27 years of experience in information systems project management, architecture, analysis, and implementation.
I specialize in highly technical software architectures and development involving the very latest technologies. With several years experience in object-oriented design and development, I am able to produce workable designs for most object-oriented languages and design environments available today. Have a thorough understanding of software development life cycles and methodologies. Coached development teams on software engineering, including project management, database design and process design. Communicate effectively to, and wins respect from, both board members and hard-core development staff.
Notable projects include: Share Point web parts and other customizations; Colored Petri-net engine; Knowledge management system; .NET based RDF data store; several persistent object stores; Wireless Field Force Automation; Wireless E-commerce work order system; B2B e-commerce purchase order system; survey package; catalog purchasing system; SGML document viewing system; stock and bond trading system; accounting systems; project management applications; Electronic Mail and electronic library systems; EAI engine system architecture.
Other projects were developed as early as 1980, involving the networking of mainframes and personal computers.
Published author, inventor and member of the IEEE Computing Society.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 30 Dec 2007
Article Copyright 2007 by AGD-H
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid