A.2. Building a Custom Solution Using the VSeWSS

In order to appreciate how VSeWSS can improve the SharePoint development experience by eliminating some of the cyclical activities involved in creating a SharePoint solution, it is best to build a robust example solution employing all of the options that VSeWSS offers. This appendix provides a detailed overview of VSeWSS architecture, showing each element that composes VSeWSS, as well as demonstrating some portions that can be extended to include various enterprise development standards, and explaining how each of the faculties that the extensions provide can be exploited to its maximum potential to construct robust, effective, manageable business solutions (see Figure A-1). The end result, achieved solely by using VSeWSS, is a powerful, easily deployable, manageable corporate policy management site that leverages all of the custom solutions created.

This section starts by building the foundation for a corporate policy management site using a custom Site Definition Project Template, which can provision the new site with appropriate assets needed for global deployment scenarios. Within the site, there will be particular custom files that ought to be included with the rest of the custom content; therefore, the definition of a custom module to be packaged with the Site Definition is provided. Second, a new content type will be generated, since the policy library used for corporate policies will have specific properties (columns), policy templates, listform pages, and event handlers associated with it. Third, there is a demonstration of how to use the List Definition template in order to build a custom document library template to house the relevant documents based on the generated content type, which also plays a pivotal role in the overall site development. Fourth, using the WebPart Project Template to perform one of the most common tasks in SharePoint provides a new way of looking at managing child subsites, since policy document workspaces are frequently used for important pieces of information such as corporate policies. Last, you will see how to propagate the custom development throughout the enterprise easily using the inherent SharePoint solution deployment options, as well as pull the site back down using the stand-alone SharePoint Solution Generator.

Figure A.1. Figure A-1

A.2.1. Architecture of and Extending VSeWSS Item and Project Templates

VSeWSS core functionality is provided as a set of Visual Studio Project and Item Templates for use with C# projects. As I write this, VSeWSS only supports C#, although it would be reasonable to expect VB.NET support in the future. These templates are stored in the appropriate Visual Studio Project and Item template directories:

Project Template Directory
C:Program FilesMicrosoft Visual Studio 8Common7IDEProjectTemplatesCSharpSharePoint

Item Template Directory
C:Program FilesMicrosoft Visual Studio 8Common7IDEItemTemplatesCSharpSharePoint

The ProjectTemplates directory houses all the options that are available when starting with a fresh Visual Studio Project instance; therefore, they are only offered when you are not adding one of the VSeWSS items to a currently existing solution file. Through the project selection screen, you can create a Team Site Definition, Blank Site Definition, List Definition, Web Part, or Empty Project File (See Figure A-2).

Once one of the boilerplate templates is instantiated and a new solution file has been created, the projects that are available in the ItemTemplates directory become available within the Solution Explorer. Through the Item Selection screen, you can create a new List Definition, List Definition from content type, content type, field control, Web Part, or module (See Figure A-3).

Figure A.2. Figure A-2

Figure A.3. Figure A-3

A.2.1.1. The Vstemplate Parent Element and Extending the VSeWSS Templates

Each of the VSeWSS Visual Studio project templates is composed of an overlying XML vstemplate project file that defines various attributes about the project, containing a parent VSTemplate node that houses child elements of the project or list instances. Collectively, within the project templates there are two major assets that can be considered universal and one more infrequently used item, which only appears when using the templates that require some user interaction, such as defining base types or provisioning of event receivers. The two common elements are TemplateData and TemplateContent, and the more infrequently used element is WizardData, which is used to harvest extended, user-provided data after the project has been created. Because the template files contain normal XML, it is possible to extend them to include custom attributes in order to promote certain development goals. This activity should be approached with caution, since it is probable that Microsoft will continually add updates to the VSeWSS template packages, which could then negate customizations you make to the bundled files. Therefore, as a best practice it is recommended that you make copies of the relevant template files in a new template in order to construct custom templates that will survive future releases of VSeWSS. That being said, extending the templates to include custom content, code files, and activities is a powerful option that can drastically increase the overall usability of VSeWSS for specific organizations.

A.2.1.2. Extending TemplateData

TemplateData contains general information about the VSeWSS template that a developer can access from the Visual Studio interface, such as the default name of the template, the project type, the project icon, and whether or not the template will instantiate a new folder. Although a majority of the default settings that are available within the default project template are satisfactory to most SharePoint developers, it is also possible to extend the template to include other options, if desired, simply by modifying the TemplateData section by adjusting the standard elements or adding elements that are not currently built into the parent element. For example, if you're building several Web Parts that are experimental, and therefore are creating and destroying numerous projects, it is useful to set the <PromptForSaveOnCreation> element in the TemplateData element to true. This allows the storage of a SharePoint project in memory, as opposed to storing each created Web Part in the default My Projects folder.

A.2.1.3. TemplateContent

TemplateContent contains essential material references to obligatory code files, XML files, and cryptographic key pairs, alongside other miscellaneous content that may be mandatory to include if the template is to be useful. Since the TemplateData elements contain references to the files to include in a SharePoint project, they can be modified and extended to include other files in your SharePoint project. This can be extremely useful when development standards within your SharePoint environment need to be maintained, such as enforcing rules necessary for class names to conform to enterprise SharePoint naming conventions or provisioning common sets of helper classes and libraries that are used throughout an organization for conventional activities.

A.2.1.4. Extending TemplateContent to Include Common Enterprise Classes

Many enterprise environments use defined patterns, such as general exception-handling classes, for all custom development. Doing so provides a uniform pattern for defining an error-catching mechanism, which is easily maintainable, improves overall software standards, and decreases development time. Therefore, if you are using VSeWSS, it is advantageous to initially modify the templates to include some patterns that are considered standards within your corporate environment. As an example, it is feasible to modify the SharePoint WebPart template code file slightly to not only include the relevant codefiles and related project assembly references provided by VSeWSS, but also include references to custom assemblies and include custom code files. Because the Web Part template exists as both a project- and item-level template, it must be modified in both directories.

If a common custom assembly houses the exception-handling classes, simply reference the assembly in the WebPart.vstemplate in the <ItemGroup> parent element. The exact reference is established in the child element <Reference Include>. For example, to add a reference to a general common exception library, add <Reference Include="ProSharePoint.Practices.Common.Exception.Example" />. Then, implement a using statement in the code for the exception handler by opening the main C# Web Part file (WebPart1.cs) in the ProjectTemplate and ItemTemplate directories and adding using ProSharePoint.Practices.Common.Exception.Example.

If there isn't a distributed precompiled assembly from which to inherit the exception classes, it is possible to adjust the default template-provided Web Part code from the WebPart template to include functionality such as writing custom Web Part errors to the event log using the EventLog.WriteEntry method of the System.Diagnostics namespace. That's particularly a superior practice for hosted environments because local listener log files for a custom Web Part that writes to the hosting assembly directory are typically inaccessible from outside. For example, you could use the following code in order to write log files to the location of where a Web Part assembly is located by using the Assembly.GetExecutingAssembly method of the System.Reflection namespace.

private static TextWriterTraceListener _listener;
private static Stream _logFile;
string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
+ @"LogFile_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".log";
_logFile = File.Create(directory);
_listener = new TextWriterTraceListener(_logFile);
Trace.Listeners.Add(_listener);

However, through the Web Event Viewer, MOSS provides the faculty, so all exceptions spawned from custom code can be viewed if using System.Diagnostics.EventLog. This is a very powerful standard for custom deployment options where control of the server is not possible. The Web Part project template can be extended to immediately provide some code to create a new event log source if one doesn't exist for the solution or to add TraceLevel information to an existing event log if the event source is found to exist (see Listing A-1).

Example A.1. Modified WebPart1.cs with common exception-handling class
//References made by VSeWSS
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

// Added to facilitate example of writing to event log for WebPart
using System.Diagnostics;

namespace $safeitemname$

{
    [Guid("$guid2$")]
    public class $safeitemname$ : System.Web.UI.WebControls.WebParts.WebPart
    {
        private static TraceSwitch traceSwitch;

        public $safeitemname$()
        {

            this.ExportMode = WebPartExportMode.All;
           traceSwitch = new TraceSwitch("MyWebPart ", "Tracing For My WebPart");
        }

        protected override void Render(HtmlTextWriter writer)
        {
            // TODO: add custom rendering code here.
            // writer.Write("Output HTML");
        }

           #region Corporate Event Log Standard For Exception Handling
           //=================================================================
           //Corporate standard exception handling classes
           //Corporate standard class to write errors to event log sources
            private static void WriteEventLog(TraceLevel TraceLevel, string Message)
        {
            EventLogEntryType eventType;
            switch (TraceLevel)
            {
                case TraceLevel.Error:
                    eventType = EventLogEntryType.Error;
                    break;

                case TraceLevel.Warning:
                    eventType = EventLogEntryType.Warning;
                    break;

                default:
                    eventType = EventLogEntryType.Information;
                    break;
            }
            if (!EventLog.SourceExists("WebPart1.cs"))
            {
                EventLog.CreateEventSource("WebPart1.cs", "Application");
            }
            EventLog logObject = new EventLog();
            logObject.Source = "WebPart1.cs";
            logObject.WriteEntry(Message, eventType);
        }

        //Helper class for writing errors to the event log
        internal static void exceptionWriteLine(DateTime time, TraceLevel
TraceLevel, string Message, string Category)
        {

int cLevel = (int)TraceLevel;
            if ((cLevel <= 2) || (((TraceLevel)cLevel) <= traceSwitch.Level))
            {
                Trace.WriteLine(time.ToString() + " : " + Message, Category);
            }
            if ((cLevel != 4) && (((TraceLevel)cLevel) <= traceSwitch.Level))
            {
                WriteEventLog(TraceLevel, Category + ": " + Message);
            }
        }

      //Property for trace level to set accessor
     internal static System.Diagnostics.TraceLevel TraceLevel
        {
            get
            {
                return traceSwitch.Level;
            }
            set
            {
                traceSwitch.Level = value;
            }
        }
#endregion

    }
}

A.2.1.5. WizardData

The WizardData element appears in Project and Item Templates that require some level of interaction before item or project creation, most frequently those that are derived from either a base object or assets that can provision a related event receiver. The WizardExtension elements that are used by VSeWSS rely on custom code from the Microsoft.SharePoint.Tools.Wizards assembly to build dialogs, which instantiate an explicit wizard interface by calling the specific a class name, such as ListDefinitionProjectWizard for a List Definition project. WizardExtensions and WizardData are common elements in templates where the content being leveraged within the template is subject to change based on user interaction. Take, for example, a SharePoint List Definition. The list that is going to be created can vary heavily based on the base List Definition that is used. In content-type-derived lists, the available content types used as a base content type will differ from project to project. Furthermore, both List Definitions and content types might also optionally leverage event receivers.

The Wizard Element contains the concept of Replacement Parameters, which will be found in other templates. Replacement Parameters allow dynamic substitution to make the project template more adaptable to project needs, so that predefined arguments can be consumed or pieces that have been custom developed can be leveraged. In essence, Replacement Parameters will allow VSeWSS project templates to be aware that the source files contain parameters, which are fundamentally placeholders for things like $safeitemname$, demonstrated in the WebPart template, that are going to be replaced when the project is created. For example, in the List Definition Project Template, a child type element <ListDefinition Type> exists within the <ListDefinitions> parent element, denoting the list type that is being created. For example, the document library List Definition looks like <ListDefinition Type="DocumentLibrary" Name="Document Library">. Within this type declaration, there are the references to specific files that are going to be included within the project template file; if certain placeholders within the file are going to be subject to replacement, they are decorated with ReplaceParameters="true". For instance, the list schema.xmlfile is included by the declaration ProjectItem TargetFileName="schema.xml">ListDefinitionsDocumentLibraryschema.xml</ProjectItem>. This is because within the schema.xml file in the VSeWSS List Definition template, you can see several variables denoted by the $ prefix and suffix, such as Title="$projectname$", constituting something that will be replaced. Although the WizardData section is a fundamental segment of VSeWSS, it is typically not extended, since there are precompiled methods that are called from it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.190.153.63