Jun 27, 2007

Nant Intellisense with Nant Contrib tasks and VS2005 nant Addin

Nant Intellisense with Nant Contrib tasks and VS2005 nant Addin.

First task is to generate the XSD (schema) file that needs to be added inorder to enable intellisense.
use the following Nant .build script to generate the nant.xsd file:

<project name="nant" default="go">
<property name="NAntContrib" value="c:\rohit\nantcontrib-0.85\bin" />
<target name="go">
<loadtasks assembly="${NAntContrib}\NAnt.Contrib.Tasks.dll" />
<nantschema output="nant.xsd" target-ns="http://nant.sf.net/nightly/2006-03-08-0.85/nant.xsd"/>

Build this script using nant:
nant /f:nantxsd.build
This will create the nant.xsd file.

Copy this file nant.xsd to 'C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml' on your system, or if you are using VS2005 then copy to "C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas".

In your NAnt build file (I make my with the extension .build) include this xmlns attribute:
<project xmlns="http://nant.sf.net/nightly/2006-03-08-0.85/nant.xsd" name="test" default="build">

Now you will get intellisense for all nant tasks as well nant contrib tasks.
To add the Nant Addin for VS2005.
Download Nant addin from:

Create a directory for Visual Studio Addins ex : "%Program Files%/Microsoft Visual Studio 8/Addins" Copy the NAntAddin directory along with the "NAntAddin.AddIn" file into it.

open VS2005. click Tools\Options.
Click on Envrironment\"Add-in/Macros Security"
Then click "Add" to add the "%Program Files%/Microsoft Visual Studio 8/Addins" directory.

Restart VS 2005.
Then click Tools\Add-in Manager.
Then check the checkbox against "NantAddin".

Now you will be able to run nant scripts or part of it directly from within VS2005.

kick it on DotNetKicks.com

Turning an ascx user control into a redistributable custom control

This is possible using the new binary compilation feature of ASP.NET 2.0 and also the availability of the ClassName property on the user control.
The ClassName property allows to specify the Namespace that is needed when consuming the usercontrol from another application.

We can publish multiple controls within a single assembly but we have to insure that the Web project contains just UserControls only (ascx along with the associated code behind files).
But if you use the "use fixed naming and single page assemblies" option then a separate assembly for each user control will be generated. However the advantage of using this option is that if you were to make changes and deploy a newer version of the user control, then you need not modify the consuming application.

This is since the assembly NAME will remain the same on each compilation of the user control project and thus we do not need to update the reference to the user control assembly from within the consuming application.

There is one more option if you decide to use the "use fixed naming and single page assemblies".
After separate assemblies are created using the Publish Website option (or using the aspnet_compiler.exe tool) we can then merge these assemblies into a single assembly using the aspnet_merge.exe tool. Another option to combine multiple user controls into a single assembly is by using the Web deployment projects (WDP).

Read this excellent MSDN magazine article by Fritz Onion on Web Deployment projects (WDP) and for info about packaging user controls into assembly for multi application use:

So the steps for converting a user control into a redistributable custom control are:
1. Create the User control in a Website project in VS2005.
The main restriction is that the User Control needs to be self contained. That is, it cannot be dependent on app global things like App_Code or global.asax. If you do need to use the App_Code folder then you could use WDP or aspnet_merge.exe to combine mutiple assemblies into a single assembly.

When you create the User Control (say MyTestUC.ascx), VS creates it with the a @control directive that looks like this:
<%@ Control Language="C#" ClassName="MyTestUC" %>

This is fine, except for one thing: we want the class to live within a namespace of our choice (instead of 'ASP', which is what's used by default). To do this, we simply modify the ClassName attribute to include the namespace (this is a new feature in 2.0). e.g.

<%@ Control Language="C#" ClassName="Acme.MyTestUC" %>

2. Publish the website to compile the user control into a assembly.
Note you need to "uncheck" 'Allow this precompiled site to be updatable' option within "Publish Website", or you can use aspnet_compiler along with -u switch to create a binary deployment of the user controls.

3. Add reference to the generated assembly in step 2 from within the consuming web application.
First, add a Register directive to your page. It should look something like this:

<%@ Register TagPrefix="Acme" Namespace="Acme" Assembly="App_Web_mytestuc.ascx.cdcab7d2" %>
Note here that the assembly name is "App_web_mytestuc.ascx.cdcab7d2"
This assembly was generated using the "use fixed naming and single page assemblies"

the reference the user control within the page of the consuming application like this:
<Acme:MyTestUC id="MyUC" runat="server" />

If you had multiple user controls within that single assembly you could then reference the second control from that assembly likewise:
<Acme:MyTestUC2 id="MyUC2" runat="server" />

That is all that is there to it.

kick it on DotNetKicks.com