Using IOptions from .NET Core in .NET Framework 4.5.1+ - Ninject dependency injection version
Configuration Management in Legacy .NET Applications (.NET Framework 4.5.1+)
I wanted to use the cool IOptions interface to grab some configs from appsettings.json. The sad thing is that it's intended to be used with .NET Core but the article mentioned above tells us that we can circumvent that with some extension code.
I won't be able to use it anymore because I just found out that I can't in the current project setup I'm working on.
As I had already converted the AutoFac code to Ninject, I'm just sharing it here in case it's useful...
You'll need to test it.
Note: make sure you have installed the following NuGet packages:
- Microsoft.Extensions.Configuration
- Microsoft.Extensions.Options
- Microsoft.Extensions.Options.ConfigurationExtensions
SVN, Hudson & MSBuild - Building code on post commit
SVN, Hudson and MSBuild - Revision control repository
SVN, Hudson and MSBuild - Continuous Integration
This is the third and last installment in the series I’m writing about SVN, Hudson and MSBuild.
Today I’m going to show you the last piece that actually makes the whole thing work. We could call this the plumbing. The piece lies within a specific SVN folder related to your project. It’s called hooks. The path to the hooks folder is this:
Figure 1 - Project’s hooks folder before the setup
As you can see there are some template files ( .tmpl ). The one we’re going to use to inform Hudson that it’s time to build the code just committed to the repository is the file post.commit.tmpl. Make a copy of this file and change its extension to .bat since it’ll be used by SVN to execute some commands. The file should be named post-commit.bat.
Open the .bat file and add this code at the end:
SET REPOS=%1
SET REV=%2
SET CSCRIPT=C:\WINDOWS\system32\cscript.exe
SET VBSCRIPT=C:\svn\post-commit-hook-hudson.vbs
SET SVNLOOK=C:\Program Files\VisualSVN Server\bin\svnlook.exe
SET HUDSON=http://leniel-pc:8080/
"%CSCRIPT%" "%VBSCRIPT%" "%REPOS%" %REV% "%SVNLOOK%" %HUDSON%
Note above that we’re setting some vars and pointing to some specific files:
- CSCRIPT points to cscript.exe file that should be present in your Windows system32 folder.
- VBSCRIPT points to to the post-commit-hook-hudson.vbs file and its code is as follows:
repos = WScript.Arguments.Item(0)
rev = WScript.Arguments.Item(1)
svnlook = WScript.Arguments.Item(2)
hudson = WScript.Arguments.Item(3)
Set shell = WScript.CreateObject("WScript.Shell")
Set uuidExec = shell.Exec(svnlook & " uuid " & repos)
Do Until uuidExec.StdOut.AtEndOfStream
uuid = uuidExec.StdOut.ReadLine()
Loop
Wscript.Echo "uuid=" & uuid
Set changedExec = shell.Exec(svnlook & " changed --revision " & rev & " " & repos)
Do Until changedExec.StdOut.AtEndOfStream
changed = changed + changedExec.StdOut.ReadLine() + Chr(10)
Loop
Wscript.Echo "changed=" & changed
url = hudson + "subversion/" + uuid + "/notifyCommit?rev=" + rev
Wscript.Echo url
Set http = CreateObject("Microsoft.XMLHTTP")
http.open "POST", url, False
http.setRequestHeader "Content-Type", "text/plain;charset=UTF-8"
http.send changed
- SVNLOOK points to svnlook.exe file that comes with VisualSVN Server (see part 1 of this series for more details about it).
- HUDSON points to your Hudson server address. Change it accordingly.
With it all configured we should be ready to get an automatic build when code is committed to the repository.
To test your environment, change any file already versioned and commit it. Open Hudson in your browser and watch a new build start automatically.
If you look in Hudson’s build Console Output you’ll see that the build was initiated by an SCM change.
That’s all!
This is how your SVN project hooks folder should look like now:
Figure 2 - Project’s hooks folder after the setup
Can you spot another .bat file in the folder? It’s the pre-revprop-change.bat. I’ve been using it so that I can modify the commit’s log message/comment when I forget to mention something or to correct spelling. More info about this file can be seen in this StackOverflow question: What is a pre-revprop-change hook in SVN and how do I create it?
Labels: .NET Framework , batch file , continuous integration , hooks , Hudson , MSBuild , repository , revision control , software engineering , svn , tools , TortoiseSVN , VisualSVN Server
SVN, Hudson and MSBuild - Continuous Integration
SVN, Hudson and MSBuild - Revision control repository
SVN, Hudson and MSBuild - Building code on post commit
This is the second installment in the series I’m writing about SVN, Hudson and MSBuild.
This time I’ll show you how to set up a job in Hudson to build and package an ASP.NET MVC 3 Hello World sample app (download it here). This job will point to the SVN repository set up in the 1st part of this series. I’ve committed the app’s source code to the trunk folder and it’s now versioned.
Question: Why should I use a Continuous Integration ( CI ) process?
Because it allows you to fine tune and extend your build process. You’ll be able to plug hooks in various stages of your build process. CI gives you more control over the process allowing an infinite set of possibilities as for example an automated build => test => package => deploy scenario.
In this post I’m going to show this simple workflow: build => package
So, to start off, the first thing you should do is to download Hudson at http://hudson-ci.org/. The latest production version is 2.1.0 as of the time of this post. Download the .war file (53.3 MB) to your C:/ drive to keep things at hand. When the download finishes, read this thorough installation guide: Install Hudson as a Windows service. This is how I’ve set up Hudson. There should be no errors if you follow the instructions.
Note
Open a command prompt at C:\ and type:
java -jar hudson-2.1.0.war
This will start Hudson and you should be able to install it as a service following this link.
Now I suppose you have Hudson working on your machine.
Head over to you Hudson instance that is located at this URL by default:
http://localhost:8080/
Let’s configure a new Job in Hudson:
Figure 1 - Selecting New Job in Hudson dashboard
When you click the New Job link you go to a screen where you can give a name to the job and choose what kind of build you want the job to execute.
I named the job HelloWorldMvc3 and selected Build a free-style software project because it fits the purpose of this series.
* As you can see I already have a job called FitnessCenter configured.
Figure 2 - Naming the New Job and selecting the build type
After clicking OK we go to a new page that allows us to enter detailed configuration settings. The following image shows the options I used (click the image to enlarge it):
Figure 3 - Configuring the job and adding a Visual Studio project or solution build step
Note above in the Source Code Management section that I have chosen Subversion and passed the Repository URL:
file:///C:/svn/MyProject/trunk
The path above is related to the SVN repository I set up here.
The sample ASP.NET MVC 3 Hello World app is located in the /trunk folder.
Now we must add a build step to tell Hudson we want to build and package the app as part of the job execution. I have highlighted the option in blue in Figure 3 above. I selected Build a Visual Studio project or solution using MSBuild.
When you add that build step you must pass some info to Hudson as shown in the following picture:
Figure 4 - Selecting MSBuild version, filling MSBuild Build File and specifying the command line arguments
MsBuild Build File = the path to the .proj or .sln file that MSBuild will use to build. This path is related to the trunk folder structure you have. In this case I have this folder structure:
C:\MyProject\trunk\HelloWorldMvc3\HelloWorldMvc3.csproj
Command Line Arguments = a whitespace separated list of command line arguments you can specify. These can be the same as if you were to run msbuild from the command line.
I used these command line arguments above to package the app:
/T:Package /P:Configuration=Release;
SolutionDir="C:\hudson\jobs\MyProject\workspace\;
PackageLocation="C:\MyProject\Package.zip"
These command line arguments are power in our hands…
You can also select post-build actions as to send an e-mail notification. If configured, Hudson will send out an e-mail to the specified recipients when a certain important event occurs:
1 - Every failed build triggers a new e-mail.
2 - A successful build after a failed (or unstable) build triggers a new e-mail, indicating that a crisis is over.
3 - An unstable build after a successful build triggers a new e-mail, indicating that there's a regression.
4 - Unless configured, every unstable build triggers a new e-mail, indicating that regression is still there.
When you finish the configuration, make sure to click the Save button.
This is everything you need to configure a new job in Hudson.
With this we achieved our objective, that is, Hudson and SVN are now plugged.
To run the job and build the app I just have to click the Build Now link in Hudson panel (see left menu bar at the top in Figure 3) but the great thing about a Continuous Integration process it to have the build process happen automatically and this is definitely possible.
Summary
Hudson is a free CI server which makes it a viable option for the majority of developers and companies out there that don’t want to spend a lot of money with equivalent expensive software. Besides, as you saw in this post you can get it working with Subversion in a couple of minutes.
Hudson has a lot of additional goodies that you can and should explore. Go over each menu option to learn about its additional features.
Next in this series
In the next and final part of this series I’m going to show you what’s missing to get SVN to inform Hudson that it’s time to build the code just committed to the repository. In the meanwhile I’ll entertain you with the Console Output regarding the first execution of the job we created in this post. It took only 08.33 seconds to build and package the app in a beautiful .zip package that can be used to deploy the app in IIS (I'll do a blog post about this topic in the future):
Started by user anonymous Checking out file:///C:/svn/MyProject/trunk A HelloWorldMvc3.sln AU HelloWorldMvc3.suo A HelloWorldMvc3 A HelloWorldMvc3\HelloWorldMvc3.csproj A HelloWorldMvc3\Properties A HelloWorldMvc3\Properties\AssemblyInfo.cs A HelloWorldMvc3\Web.Release.config A HelloWorldMvc3\packages.config A HelloWorldMvc3\Global.asax A HelloWorldMvc3\Controllers A HelloWorldMvc3\Controllers\HomeController.cs A HelloWorldMvc3\Controllers\AccountController.cs A HelloWorldMvc3\Web.Debug.config A HelloWorldMvc3\App_Data A HelloWorldMvc3\Scripts A HelloWorldMvc3\Scripts\modernizr-1.7.js A HelloWorldMvc3\Scripts\jquery.validate.js A HelloWorldMvc3\Scripts\jquery.unobtrusive-ajax.js A HelloWorldMvc3\Scripts\MicrosoftMvcValidation.js A HelloWorldMvc3\Scripts\jquery.validate-vsdoc.js A HelloWorldMvc3\Scripts\MicrosoftMvcAjax.js A HelloWorldMvc3\Scripts\jquery.validate.unobtrusive.min.js A HelloWorldMvc3\Scripts\MicrosoftMvcValidation.debug.js A HelloWorldMvc3\Scripts\jquery-1.5.1-vsdoc.js A HelloWorldMvc3\Scripts\MicrosoftMvcAjax.debug.js A HelloWorldMvc3\Scripts\jquery-ui-1.8.11.min.js A HelloWorldMvc3\Scripts\jquery-1.5.1.min.js A HelloWorldMvc3\Scripts\MicrosoftAjax.js A HelloWorldMvc3\Scripts\jquery-ui-1.8.11.js A HelloWorldMvc3\Scripts\jquery-1.5.1.js A HelloWorldMvc3\Scripts\MicrosoftAjax.debug.js A HelloWorldMvc3\Scripts\modernizr-1.7.min.js A HelloWorldMvc3\Scripts\jquery.validate.min.js A HelloWorldMvc3\Scripts\jquery.unobtrusive-ajax.min.js A HelloWorldMvc3\Scripts\jquery.validate.unobtrusive.js A HelloWorldMvc3\Content A HelloWorldMvc3\Content\themes A HelloWorldMvc3\Content\themes\base A HelloWorldMvc3\Content\themes\base\jquery.ui.base.css A HelloWorldMvc3\Content\themes\base\jquery.ui.slider.css A HelloWorldMvc3\Content\themes\base\jquery.ui.button.css A HelloWorldMvc3\Content\themes\base\jquery.ui.progressbar.css A HelloWorldMvc3\Content\themes\base\jquery.ui.accordion.css A HelloWorldMvc3\Content\themes\base\jquery.ui.theme.css A HelloWorldMvc3\Content\themes\base\jquery.ui.selectable.css A HelloWorldMvc3\Content\themes\base\jquery.ui.resizable.css A HelloWorldMvc3\Content\themes\base\jquery.ui.autocomplete.css A HelloWorldMvc3\Content\themes\base\jquery.ui.dialog.css A HelloWorldMvc3\Content\themes\base\images AU HelloWorldMvc3\Content\themes\base\images\ui-bg_glass_95_fef1ec_1x400.png AU HelloWorldMvc3\Content\themes\base\images\ui-icons_2e83ff_256x240.png AU HelloWorldMvc3\Content\themes\base\images\ui-bg_flat_75_ffffff_40x100.png AU HelloWorldMvc3\Content\themes\base\images\ui-bg_glass_55_fbf9ee_1x400.png AU HelloWorldMvc3\Content\themes\base\images\ui-icons_222222_256x240.png AU HelloWorldMvc3\Content\themes\base\images\ui-icons_888888_256x240.png AU HelloWorldMvc3\Content\themes\base\images\ui-bg_glass_65_ffffff_1x400.png AU HelloWorldMvc3\Content\themes\base\images\ui-icons_454545_256x240.png AU HelloWorldMvc3\Content\themes\base\images\ui-icons_cd0a0a_256x240.png AU HelloWorldMvc3\Content\themes\base\images\ui-bg_glass_75_e6e6e6_1x400.png AU HelloWorldMvc3\Content\themes\base\images\ui-bg_flat_0_aaaaaa_40x100.png AU HelloWorldMvc3\Content\themes\base\images\ui-bg_highlight-soft_75_cccccc_1x100.png AU HelloWorldMvc3\Content\themes\base\images\ui-bg_glass_75_dadada_1x400.png A HelloWorldMvc3\Content\themes\base\jquery.ui.datepicker.css A HelloWorldMvc3\Content\themes\base\jquery.ui.all.css A HelloWorldMvc3\Content\themes\base\jquery.ui.tabs.css A HelloWorldMvc3\Content\themes\base\jquery.ui.core.css A HelloWorldMvc3\Content\Site.css A HelloWorldMvc3\Global.asax.cs A HelloWorldMvc3\Models A HelloWorldMvc3\Models\AccountModels.cs A HelloWorldMvc3\Web.config A HelloWorldMvc3\Views A HelloWorldMvc3\Views\Shared A HelloWorldMvc3\Views\Shared\_Layout.cshtml A HelloWorldMvc3\Views\Shared\Error.cshtml A HelloWorldMvc3\Views\Shared\_LogOnPartial.cshtml A HelloWorldMvc3\Views\_ViewStart.cshtml A HelloWorldMvc3\Views\Web.config A HelloWorldMvc3\Views\Account A HelloWorldMvc3\Views\Account\ChangePasswordSuccess.cshtml A HelloWorldMvc3\Views\Account\LogOn.cshtml A HelloWorldMvc3\Views\Account\Register.cshtml A HelloWorldMvc3\Views\Account\ChangePassword.cshtml A HelloWorldMvc3\Views\Home A HelloWorldMvc3\Views\Home\Index.cshtml A HelloWorldMvc3\Views\Home\About.cshtml AU HelloWorldMvc3.sln.docstates.suo A packages A packages\jQuery.UI.Combined.1.8.11 A packages\jQuery.UI.Combined.1.8.11\Content A packages\jQuery.UI.Combined.1.8.11\Content\Scripts A packages\jQuery.UI.Combined.1.8.11\Content\Scripts\jquery-ui-1.8.11.min.js A packages\jQuery.UI.Combined.1.8.11\Content\Scripts\jquery-ui-1.8.11.js A packages\jQuery.UI.Combined.1.8.11\Content\Content A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.base.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.slider.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.button.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.progressbar.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.accordion.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.theme.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.selectable.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.resizable.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.autocomplete.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.dialog.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-bg_glass_95_fef1ec_1x400.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-icons_2e83ff_256x240.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-bg_flat_75_ffffff_40x100.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-bg_glass_55_fbf9ee_1x400.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-icons_222222_256x240.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-icons_888888_256x240.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-bg_glass_65_ffffff_1x400.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-icons_454545_256x240.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-icons_cd0a0a_256x240.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-bg_glass_75_e6e6e6_1x400.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-bg_flat_0_aaaaaa_40x100.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-bg_highlight-soft_75_cccccc_1x100.png AU packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\images\ui-bg_glass_75_dadada_1x400.png A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.datepicker.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.all.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.tabs.css A packages\jQuery.UI.Combined.1.8.11\Content\Content\themes\base\jquery.ui.core.css AU packages\jQuery.UI.Combined.1.8.11\jQuery.UI.Combined.1.8.11.nupkg A packages\jQuery.Validation.1.8.0 A packages\jQuery.Validation.1.8.0\Content A packages\jQuery.Validation.1.8.0\Content\Scripts A packages\jQuery.Validation.1.8.0\Content\Scripts\jquery.validate.js A packages\jQuery.Validation.1.8.0\Content\Scripts\jquery.validate-vsdoc.js A packages\jQuery.Validation.1.8.0\Content\Scripts\jquery.validate.min.js AU packages\jQuery.Validation.1.8.0\jQuery.Validation.1.8.0.nupkg A packages\jQuery.vsdoc.1.5.1 A packages\jQuery.vsdoc.1.5.1\Content A packages\jQuery.vsdoc.1.5.1\Content\Scripts A packages\jQuery.vsdoc.1.5.1\Content\Scripts\jquery-1.5.1-vsdoc.js AU packages\jQuery.vsdoc.1.5.1\jQuery.vsdoc.1.5.1.nupkg A packages\repositories.config A packages\EntityFramework.4.1.10331.0 AU packages\EntityFramework.4.1.10331.0\EntityFramework.4.1.10331.0.nupkg A packages\EntityFramework.4.1.10331.0\lib AU packages\EntityFramework.4.1.10331.0\lib\EntityFramework.dll A packages\EntityFramework.4.1.10331.0\lib\EntityFramework.xml A packages\jQuery.1.5.1 AU packages\jQuery.1.5.1\jQuery.1.5.1.nupkg A packages\jQuery.1.5.1\Content A packages\jQuery.1.5.1\Content\Scripts A packages\jQuery.1.5.1\Content\Scripts\jquery-1.5.1.min.js A packages\jQuery.1.5.1\Content\Scripts\jquery-1.5.1.js A packages\Modernizr.1.7 AU packages\Modernizr.1.7\Modernizr.1.7.nupkg A packages\Modernizr.1.7\Content A packages\Modernizr.1.7\Content\Scripts A packages\Modernizr.1.7\Content\Scripts\modernizr-1.7.min.js A packages\Modernizr.1.7\Content\Scripts\modernizr-1.7.js At revision 2 Path To MSBuild.exe: C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Executing command: cmd.exe /C C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /T:Package /P:Configuration=Debug;SolutionDir=C:\hudson\jobs\MyProject\workspace\;PackageLocation=C:\MyProject\Package.zip HelloWorldMvc3\HelloWorldMvc3.csproj && exit %%ERRORLEVEL%% [workspace] $ cmd.exe /C C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /T:Package /P:Configuration=Debug;SolutionDir=C:\hudson\jobs\MyProject\workspace\;PackageLocation=C:\MyProject\Package.zip HelloWorldMvc3\HelloWorldMvc3.csproj && exit %%ERRORLEVEL%% Microsoft (R) Build Engine Version 4.0.30319.1 [Microsoft .NET Framework, Version 4.0.30319.454] Copyright (C) Microsoft Corporation 2007. All rights reserved. Build started 7/30/2011 12:16:23 AM. Project "C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\HelloWorldMvc3.csproj" on node 1 (Package target(s)). ValidateGlobalPackageSetting: $(PackageAsSingleFile) is True $(PackageFileName) is C:\MyProject\Package.zip. Validating... PrepareForBuild: Creating directory "bin\". Creating directory "obj\Debug\". GenerateTargetFrameworkMonikerAttribute: Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files. CoreCompile: c:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:C:\hudson\jobs\HelloWorldMvc3\workspace\packages\EntityFramework.4.1.10331.0\lib\EntityFramework.dll /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Microsoft.CSharp.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.ComponentModel.DataAnnotations.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Configuration.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.DataSetExtensions.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.Entity.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Drawing.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.EnterpriseServices.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Web.Abstractions.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Web.ApplicationServices.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Web.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Web.DynamicData.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Web.Entity.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Web.Extensions.dll" /reference:"c:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies\System.Web.Helpers.dll" /reference:"c:\Program Files\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies\System.Web.Mvc.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Web.Routing.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Web.Services.dll" /reference:"c:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies\System.Web.WebPages.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Xml.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Xml.Linq.dll" /debug+ /debug:full /optimize- /out:obj\Debug\HelloWorldMvc3.dll /target:library Controllers\AccountController.cs Controllers\HomeController.cs Global.asax.cs Models\AccountModels.cs Properties\AssemblyInfo.cs "C:\Windows\TEMP\.NETFramework,Version=v4.0.AssemblyAttributes.cs" _CopyFilesMarkedCopyLocal: Copying file from "C:\hudson\jobs\HelloWorldMvc3\workspace\packages\EntityFramework.4.1.10331.0\lib\EntityFramework.dll" to "bin\EntityFramework.dll". Copying file from "C:\hudson\jobs\HelloWorldMvc3\workspace\packages\EntityFramework.4.1.10331.0\lib\EntityFramework.xml" to "bin\EntityFramework.xml". CopyFilesToOutputDirectory: Copying file from "obj\Debug\HelloWorldMvc3.dll" to "bin\HelloWorldMvc3.dll". HelloWorldMvc3 -> C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\bin\HelloWorldMvc3.dll Copying file from "obj\Debug\HelloWorldMvc3.pdb" to "bin\HelloWorldMvc3.pdb". CollectFilesFromIntermediateAssembly: Gather all files from Project items @(IntermediateAssembly). Adding: bin\HelloWorldMvc3.dll to bin\HelloWorldMvc3.dll bin\HelloWorldMvc3.pdb to bin\HelloWorldMvc3.pdb CollectFilesFromContent: Gather all files from Project items @(Content). Adding: Content\themes\base\images\ui-bg_flat_0_aaaaaa_40x100.png;Content\themes\base\images\ui-bg_flat_75_ffffff_40x100.png;Content\themes\base\images\ui-bg_glass_55_fbf9ee_1x400.png;Content\themes\base\images\ui-bg_glass_65_ffffff_1x400.png;Content\themes\base\images\ui-bg_glass_75_dadada_1x400.png;Content\themes\base\images\ui-bg_glass_75_e6e6e6_1x400.png;Content\themes\base\images\ui-bg_glass_95_fef1ec_1x400.png;Content\themes\base\images\ui-bg_highlight-soft_75_cccccc_1x100.png;Content\themes\base\images\ui-icons_222222_256x240.png;Content\themes\base\images\ui-icons_2e83ff_256x240.png;Content\themes\base\images\ui-icons_454545_256x240.png;Content\themes\base\images\ui-icons_888888_256x240.png;Content\themes\base\images\ui-icons_cd0a0a_256x240.png;Content\themes\base\jquery.ui.accordion.css;Content\themes\base\jquery.ui.all.css;Content\themes\base\jquery.ui.autocomplete.css;Content\themes\base\jquery.ui.base.css;Content\themes\base\jquery.ui.button.css;Content\themes\base\jquery.ui.core.css;Content\themes\base\jquery.ui.datepicker.css;Content\themes\base\jquery.ui.dialog.css;Content\themes\base\jquery.ui.progressbar.css;Content\themes\base\jquery.ui.resizable.css;Content\themes\base\jquery.ui.selectable.css;Content\themes\base\jquery.ui.slider.css;Content\themes\base\jquery.ui.tabs.css;Content\themes\base\jquery.ui.theme.css;Global.asax;Scripts\jquery-1.5.1-vsdoc.js;Scripts\jquery-1.5.1.js;Scripts\jquery-1.5.1.min.js;Scripts\jquery-ui-1.8.11.js;Scripts\jquery-ui-1.8.11.min.js;Scripts\jquery.validate-vsdoc.js;Scripts\jquery.validate.js;Scripts\jquery.validate.min.js;Scripts\modernizr-1.7.js;Scripts\modernizr-1.7.min.js;Web.config;Web.Debug.config;Web.Release.config;Content\Site.css;Scripts\jquery.unobtrusive-ajax.js;Scripts\jquery.unobtrusive-ajax.min.js;Scripts\jquery.validate.unobtrusive.js;Scripts\jquery.validate.unobtrusive.min.js;Scripts\MicrosoftAjax.js;Scripts\MicrosoftAjax.debug.js;Scripts\MicrosoftMvcAjax.js;Scripts\MicrosoftMvcAjax.debug.js;Scripts\MicrosoftMvcValidation.js;Scripts\MicrosoftMvcValidation.debug.js;Views\_ViewStart.cshtml;Views\Account\ChangePassword.cshtml;Views\Account\ChangePasswordSuccess.cshtml;Views\Account\LogOn.cshtml;Views\Account\Register.cshtml;Views\Home\About.cshtml;Views\Home\Index.cshtml;Views\Shared\Error.cshtml;Views\Shared\_LogOnPartial.cshtml;Views\Shared\_Layout.cshtml;Views\Web.config;packages.config CollectFilesFromIntermediateSatelliteAssembliesWithTargetPath: Gather all files from Project output (IntermediateSatelliteAssembliesWithTargetPath). Adding: CollectFilesFromReference: Gather all files from Project items @(ReferenceCopyLocalPaths,ReferenceComWrappersToCopyLocal,ResolvedIsolatedComModules,_DeploymentLooseManifestFile,NativeReferenceFile). CollectFilesFromAllExtraReferenceFiles: Gather all files from Project items @(AllExtraReferenceFiles). Adding: CollectFilesFrom_binDeployableAssemblies: Gather all files from Project items @(_binDeployableAssemblies). Adding: PipelineCollectFilesPhase: Publish Pipeline Collect Files Phase CollectWebConfigsToTransform: Found The following for Config tranformation: Web.config, Views\Web.config Creating directory "C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\TransformWebConfig\transformed\". Creating directory "C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\TransformWebConfig\transformed\Views\". PreTransformWebConfig: Copying Web.config to obj\Debug\TransformWebConfig\original\Web.config. TransformWebConfigCore: Transforming Source File: C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\Web.config Applying Transform File: C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\Web.Debug.config Output File: obj\Debug\TransformWebConfig\transformed\Web.config Transformation succeeded PostTransformWebConfig: Transformed Web.config using Web.Debug.config into obj\Debug\TransformWebConfig\transformed\Web.config. PipelineTransformPhase: Publish Pipeline Transform Phase PreAutoParameterizationWebConfigConnectionStrings: Creating directory "C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\CSAutoParameterize\transformed\Views\". Copying Views\Web.config to obj\Debug\CSAutoParameterize\original\Views\Web.config. Copying obj\Debug\TransformWebConfig\transformed\Web.config to obj\Debug\CSAutoParameterize\original\Web.config. AutoParameterizationWebConfigConnectionStringsCore: Transforming Source File: C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\Views\Web.config Applying Transform File: <?xml version="1.0"?> <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <connectionStrings> <add connectionString="{% token='$(ReplacableToken_#(parameter)_#(tokennumber))' xpathlocator='name' parameter='$(name)-Web.config Connection String' description='$(name) Connection String used in web.config by the application to access the database.' defaultValue='$(connectionString)' tags='SqlConnectionString' %}" xdt:Transform="SetTokenizedAttributes(connectionString)" xdt:SupressWarnings="True" /> </connectionStrings> </configuration> No element in the source document matches '/configuration/connectionStrings' Not executing SetTokenizedAttributes (transform line 6, 15) Output File: obj\Debug\CSAutoParameterize\transformed\Views\Web.config Transformation succeeded Transforming Source File: C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\TransformWebConfig\transformed\Web.config Applying Transform File: <?xml version="1.0"?> <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <connectionStrings> <add connectionString="{% token='$(ReplacableToken_#(parameter)_#(tokennumber))' xpathlocator='name' parameter='$(name)-Web.config Connection String' description='$(name) Connection String used in web.config by the application to access the database.' defaultValue='$(connectionString)' tags='SqlConnectionString' %}" xdt:Transform="SetTokenizedAttributes(connectionString)" xdt:SupressWarnings="True" /> </connectionStrings> </configuration> Output File: obj\Debug\CSAutoParameterize\transformed\Web.config Transformation succeeded PostAutoParameterizationWebConfigConnectionStrings: Auto ConnectionString Transformed Views\Web.config into obj\Debug\CSAutoParameterize\transformed\Views\Web.config. Auto ConnectionString Transformed obj\Debug\TransformWebConfig\transformed\Web.config into obj\Debug\CSAutoParameterize\transformed\Web.config. CopyAllFilesToSingleFolderForPackage: Creating directory "obj\Debug\Package\PackageTmp". Copying all files to temporary location below for package/publish: obj\Debug\Package\PackageTmp. Copying bin\HelloWorldMvc3.dll to obj\Debug\Package\PackageTmp\bin\HelloWorldMvc3.dll. Copying bin\HelloWorldMvc3.pdb to obj\Debug\Package\PackageTmp\bin\HelloWorldMvc3.pdb. Copying Content\themes\base\images\ui-bg_flat_0_aaaaaa_40x100.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_flat_0_aaaaaa_40x100.png. Copying Content\themes\base\images\ui-bg_flat_75_ffffff_40x100.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_flat_75_ffffff_40x100.png. Copying Content\themes\base\images\ui-bg_glass_55_fbf9ee_1x400.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_55_fbf9ee_1x400.png. Copying Content\themes\base\images\ui-bg_glass_65_ffffff_1x400.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_65_ffffff_1x400.png. Copying Content\themes\base\images\ui-bg_glass_75_dadada_1x400.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_75_dadada_1x400.png. Copying Content\themes\base\images\ui-bg_glass_75_e6e6e6_1x400.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_75_e6e6e6_1x400.png. Copying Content\themes\base\images\ui-bg_glass_95_fef1ec_1x400.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_95_fef1ec_1x400.png. Copying Content\themes\base\images\ui-bg_highlight-soft_75_cccccc_1x100.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_highlight-soft_75_cccccc_1x100.png. Copying Content\themes\base\images\ui-icons_222222_256x240.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_222222_256x240.png. Copying Content\themes\base\images\ui-icons_2e83ff_256x240.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_2e83ff_256x240.png. Copying Content\themes\base\images\ui-icons_454545_256x240.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_454545_256x240.png. Copying Content\themes\base\images\ui-icons_888888_256x240.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_888888_256x240.png. Copying Content\themes\base\images\ui-icons_cd0a0a_256x240.png to obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_cd0a0a_256x240.png. Copying Content\themes\base\jquery.ui.accordion.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.accordion.css. Copying Content\themes\base\jquery.ui.all.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.all.css. Copying Content\themes\base\jquery.ui.autocomplete.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.autocomplete.css. Copying Content\themes\base\jquery.ui.base.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.base.css. Copying Content\themes\base\jquery.ui.button.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.button.css. Copying Content\themes\base\jquery.ui.core.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.core.css. Copying Content\themes\base\jquery.ui.datepicker.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.datepicker.css. Copying Content\themes\base\jquery.ui.dialog.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.dialog.css. Copying Content\themes\base\jquery.ui.progressbar.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.progressbar.css. Copying Content\themes\base\jquery.ui.resizable.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.resizable.css. Copying Content\themes\base\jquery.ui.selectable.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.selectable.css. Copying Content\themes\base\jquery.ui.slider.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.slider.css. Copying Content\themes\base\jquery.ui.tabs.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.tabs.css. Copying Content\themes\base\jquery.ui.theme.css to obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.theme.css. Copying Global.asax to obj\Debug\Package\PackageTmp\Global.asax. Copying Scripts\jquery-1.5.1-vsdoc.js to obj\Debug\Package\PackageTmp\Scripts\jquery-1.5.1-vsdoc.js. Copying Scripts\jquery-1.5.1.js to obj\Debug\Package\PackageTmp\Scripts\jquery-1.5.1.js. Copying Scripts\jquery-1.5.1.min.js to obj\Debug\Package\PackageTmp\Scripts\jquery-1.5.1.min.js. Copying Scripts\jquery-ui-1.8.11.js to obj\Debug\Package\PackageTmp\Scripts\jquery-ui-1.8.11.js. Copying Scripts\jquery-ui-1.8.11.min.js to obj\Debug\Package\PackageTmp\Scripts\jquery-ui-1.8.11.min.js. Copying Scripts\jquery.validate-vsdoc.js to obj\Debug\Package\PackageTmp\Scripts\jquery.validate-vsdoc.js. Copying Scripts\jquery.validate.js to obj\Debug\Package\PackageTmp\Scripts\jquery.validate.js. Copying Scripts\jquery.validate.min.js to obj\Debug\Package\PackageTmp\Scripts\jquery.validate.min.js. Copying Scripts\modernizr-1.7.js to obj\Debug\Package\PackageTmp\Scripts\modernizr-1.7.js. Copying Scripts\modernizr-1.7.min.js to obj\Debug\Package\PackageTmp\Scripts\modernizr-1.7.min.js. Copying Content\Site.css to obj\Debug\Package\PackageTmp\Content\Site.css. Copying Scripts\jquery.unobtrusive-ajax.js to obj\Debug\Package\PackageTmp\Scripts\jquery.unobtrusive-ajax.js. Copying Scripts\jquery.unobtrusive-ajax.min.js to obj\Debug\Package\PackageTmp\Scripts\jquery.unobtrusive-ajax.min.js. Copying Scripts\jquery.validate.unobtrusive.js to obj\Debug\Package\PackageTmp\Scripts\jquery.validate.unobtrusive.js. Copying Scripts\jquery.validate.unobtrusive.min.js to obj\Debug\Package\PackageTmp\Scripts\jquery.validate.unobtrusive.min.js. Copying Scripts\MicrosoftAjax.js to obj\Debug\Package\PackageTmp\Scripts\MicrosoftAjax.js. Copying Scripts\MicrosoftAjax.debug.js to obj\Debug\Package\PackageTmp\Scripts\MicrosoftAjax.debug.js. Copying Scripts\MicrosoftMvcAjax.js to obj\Debug\Package\PackageTmp\Scripts\MicrosoftMvcAjax.js. Copying Scripts\MicrosoftMvcAjax.debug.js to obj\Debug\Package\PackageTmp\Scripts\MicrosoftMvcAjax.debug.js. Copying Scripts\MicrosoftMvcValidation.js to obj\Debug\Package\PackageTmp\Scripts\MicrosoftMvcValidation.js. Copying Scripts\MicrosoftMvcValidation.debug.js to obj\Debug\Package\PackageTmp\Scripts\MicrosoftMvcValidation.debug.js. Copying Views\_ViewStart.cshtml to obj\Debug\Package\PackageTmp\Views\_ViewStart.cshtml. Copying Views\Account\ChangePassword.cshtml to obj\Debug\Package\PackageTmp\Views\Account\ChangePassword.cshtml. Copying Views\Account\ChangePasswordSuccess.cshtml to obj\Debug\Package\PackageTmp\Views\Account\ChangePasswordSuccess.cshtml. Copying Views\Account\LogOn.cshtml to obj\Debug\Package\PackageTmp\Views\Account\LogOn.cshtml. Copying Views\Account\Register.cshtml to obj\Debug\Package\PackageTmp\Views\Account\Register.cshtml. Copying Views\Home\About.cshtml to obj\Debug\Package\PackageTmp\Views\Home\About.cshtml. Copying Views\Home\Index.cshtml to obj\Debug\Package\PackageTmp\Views\Home\Index.cshtml. Copying Views\Shared\Error.cshtml to obj\Debug\Package\PackageTmp\Views\Shared\Error.cshtml. Copying Views\Shared\_LogOnPartial.cshtml to obj\Debug\Package\PackageTmp\Views\Shared\_LogOnPartial.cshtml. Copying Views\Shared\_Layout.cshtml to obj\Debug\Package\PackageTmp\Views\Shared\_Layout.cshtml. Copying packages.config to obj\Debug\Package\PackageTmp\packages.config. Copying C:\hudson\jobs\HelloWorldMvc3\workspace\packages\EntityFramework.4.1.10331.0\lib\EntityFramework.dll to obj\Debug\Package\PackageTmp\bin\EntityFramework.dll. Copying C:\hudson\jobs\HelloWorldMvc3\workspace\packages\EntityFramework.4.1.10331.0\lib\EntityFramework.xml to obj\Debug\Package\PackageTmp\bin\EntityFramework.xml. Copying obj\Debug\CSAutoParameterize\transformed\Views\Web.config to obj\Debug\Package\PackageTmp\Views\Web.config. Copying obj\Debug\CSAutoParameterize\transformed\Web.config to obj\Debug\Package\PackageTmp\Web.config. PipelinePreDeployCopyAllFilesToOneFolder: Publish Pipeline Deploy phase Pre-Deploy CopyAllFilesToOneFolder Stage Package: Invoking Web Deploy to generate the package with the following settings: $(LocalIisVersion) is 7 $(DestinationIisVersion) is 7 $(UseIis) is False $(IncludeIisSettings) is False $(_DeploymentUseIis) is False $(DestinationUseIis) is False GenerateMsdeployManifestFiles: Generate source manifest file for Web Deploy package/publish ... CollectDatabasesToPublish: Creating directory "obj\Debug\Database". PackageUsingManifest: Packaging into C:\MyProject\Package.zip. Starting Web deployment task from source:manifest(C:\MyProject\Package.SourceManifest.xml) to Destination:package(C:\MyProject\Package.zip). Adding package (package). Adding child iisApp (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp). Adding child createApp (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp). Adding child contentPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\bin). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\bin\EntityFramework.dll). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\bin\EntityFramework.xml). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\bin\HelloWorldMvc3.dll). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\bin\HelloWorldMvc3.pdb). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\Site.css). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_flat_0_aaaaaa_40x100.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_flat_75_ffffff_40x100.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_55_fbf9ee_1x400.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_65_ffffff_1x400.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_75_dadada_1x400.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_75_e6e6e6_1x400.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_glass_95_fef1ec_1x400.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-bg_highlight-soft_75_cccccc_1x100.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_222222_256x240.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_2e83ff_256x240.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_454545_256x240.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_888888_256x240.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\images\ui-icons_cd0a0a_256x240.png). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.accordion.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.all.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.autocomplete.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.base.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.button.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.core.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.datepicker.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.dialog.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.progressbar.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.resizable.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.selectable.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.slider.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.tabs.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Content\themes\base\jquery.ui.theme.css). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Global.asax). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\packages.config). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery-1.5.1-vsdoc.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery-1.5.1.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery-1.5.1.min.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery-ui-1.8.11.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery-ui-1.8.11.min.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery.unobtrusive-ajax.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery.unobtrusive-ajax.min.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery.validate-vsdoc.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery.validate.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery.validate.min.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery.validate.unobtrusive.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\jquery.validate.unobtrusive.min.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\MicrosoftAjax.debug.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\MicrosoftAjax.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\MicrosoftMvcAjax.debug.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\MicrosoftMvcAjax.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\MicrosoftMvcValidation.debug.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\MicrosoftMvcValidation.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\modernizr-1.7.js). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Scripts\modernizr-1.7.min.js). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Account). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Account\ChangePassword.cshtml). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Account\ChangePasswordSuccess.cshtml). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Account\LogOn.cshtml). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Account\Register.cshtml). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Home). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Home\About.cshtml). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Home\Index.cshtml). Adding child dirPath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Shared). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Shared\Error.cshtml). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Shared\_Layout.cshtml). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Shared\_LogOnPartial.cshtml). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\Web.config). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Views\_ViewStart.cshtml). Adding child filePath (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp\Web.config). Adding child setAcl (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp). Adding child setAcl (C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\obj\Debug\Package\PackageTmp). Adding declared parameter 'IIS Web Application Name'. Adding declared parameter 'ApplicationServices-Web.config Connection String'. Successfully executed Web deployment task. Package "Package.zip" is successfully created as single file at the following location: file:///C:/MyProject To get the instructions on how to deploy the web package please visit the following link: http://go.microsoft.com/fwlink/?LinkId=124618 GenerateSampleDeployScript: Sample script for deploying this package is generated at the following location: C:\MyProject\Package.deploy.cmd For this sample script, you can change the deploy parameters by changing the following file: C:\MyProject\Package.SetParameters.xml Done Building Project "C:\hudson\jobs\HelloWorldMvc3\workspace\HelloWorldMvc3\HelloWorldMvc3.csproj" (Package target(s)). Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:08.33 Finished: SUCCESS
Labels: .NET Framework , continuous integration , Hudson , MSBuild , repository , revision control , software engineering , svn , tools
SVN, Hudson and MSBuild - Revision control repository
SVN, Hudson and MSBuild - Continuous Integration
SVN, Hudson and MSBuild - Building code on post commit
This three part series of posts I’m starting today serves as a guide on how to setup a continuous integration/CI server.
Tools I’m going to use (all FREE) and a brief description of them:
Hudson monitors executions of repeated jobs, such as building a software project or jobs. Hudson helps building/testing software projects continuously. In a nutshell, Hudson provides an easy-to-use so-called continuous integration system, making it easier for developers to integrate changes to the project, and making it easier for users to obtain a fresh build. The automated, continuous build increases the productivity.
MSBuild (Visual Studio 2010 native build system)
The Microsoft Build Engine (MSBuild) is the build platform for Microsoft and Visual Studio. MSBuild is completely transparent with regards to how it processes and builds software, enabling developers to orchestrate and build products in build lab environments where Visual Studio is not installed.
TortoiseSVN is an easy-to-use SCM / source control software for Microsoft Windows and possibly the best standalone Apache™ Subversion® client there is. It is implemented as a Windows shell extension, which makes it integrate seamlessly into the Windows explorer. Since it's not an integration for a specific IDE you can use it with whatever development tools you like.
VisualSVN Server allows you to easily install and manage a fully-functional Subversion server on the Windows platform. Thanks to its robustness, unbeatable usability and unique enterprise-grade features, VisualSVN Server is affordable both for small business and corporate users. It greatly simplifies installing and managing Subversion and is available for free.
The series will focus on continuous integration of .NET family of projects and I’ll write things in the order I installed them.
This 1st part will deal with the Revision Control repository configuration.
The only difference here is that I’m running all these software engineering tools on my Windows 7 virtual machine that is used exclusively for software development. A more ubiquitous situation is when/where you have each one of these tools working on their specific servers, that is, you’ll frequently see a dedicated continuous integration server, a dedicated build server and a dedicated repository server.
Having dedicated servers is good for a software development team/company. This definitely isn’t my case. I’m doing solo work and as such I decided to have a stable environment which can give me all the benefits of a continuous integration process running in a single machine (cost effective solution). This allows me to apply a better quality control over my code and at the same time I can automate common tasks.
These tools are working great on my machine right now where I’m developing and integrating an ASP.NET MVC 3 application. Bellow I’ll describe what you need in order to get a revision control repository running in your development machine.
I try to simplify every step going to the point and avoiding the intrinsic aspects such as why things are named or done this or that way.
When you finish this step by step guide, the following question should be answered:
Question: How/Why should I put my code under revision control?
Valid answer:
1 - Download and install TortoiseSVN. TortoiseSVN is a Subversion client.
2 - Create the SVN folder for your project. For example in C:\svn\MyProject. Right-click this folder and select TortoiseSVN → Create repository here. You should get a confirmation message like this one:
Figure 1 - Repository Successfully Created
3 - Create this temporary folder structure so that you have a standard SVN folder layout:
C:\Temp\MyProject\trunk
C:\Temp\MyProject\branches
C:\Temp\MyProject\tags
Do not mind the Temp folder for now. The main idea here is that you’ll put you current project’s folders/files inside the trunk folder. For more on this, read revision control.
4 - Move all MyProjects’s code to the trunk folder.
5 - Now right click the folder C:\Temp\MyProject and select TortoiseSVN → Import… Now you must provide the SVN address where you want to import your project. Do this:
Figure 2 - Import
Note the slashes ( / ) instead of back slashes ( \ ).
Before you import the project into the repository take note of:
- Just import the content needed to build the project. Remove unnecessary or temporary files/folders generated by the compiler e.g. Files = *.suo/*.user and folders = Bin/obj that contain compiled binaries.
- Organize your project in folders and subfolders. Using TortoiseSVN you can later rename/move files but it’s highly recommended that you set your project’s structure before importing!
After clicking OK, you should see this:
Figure 3 - MyProject Import Finished
Great. Now we have just imported MyProject’s files to a revision control repository. See that we are at revision 1.
Now we’re going to check out this code in a different folder so that we can have the benefits of revision control.
6 - Create the folder C:\MyProject.
7 - Right click C:\MyProject and select SVN Checkout…
Figure 4 - Checkout
After clicking OK, you should get this:
Figure 5 - Checkout Finished
You’ll see that Windows Explorer now shows an icon in each file/folder informing that that specific file/folder is up to date or not with the one we have in the SVN repository:
Figure 6 - Windows Explorer with Project Under Version Control
As you can see, I have changed the content of the file Main line Project Files and Folders go here.txt and as a result of this action I’m informed that this file was changed since the last check out (red exclamation mark). When I perform a commit to the repository this file that is marked as modified will be part of the head revision of the repository.
TortoiseSVN context menu options
SVN is a really powerful tool that has a lot of functions as the revision graph selected bellow:
Figure 7 - TortoiseSVN Context Menu Options
You’ll learn about and use each one of these functions for sure as the time passes by. Do not panic and take it easy! Be careful though when performing a commit to the repository and avoid breaking things. This can cause headaches.
Summary
In this simple step by step guide you saw how to put a project under revision control. This gives you a cool way of keeping track of what has been added, deleted, changed in your project since its start through what we call revisions. In addition you also get the chance of rolling back your changes in case anything goes wrong. This I think is the greatest feature of a revision control repository, that is, it acts in such a way that if I later decide to rollback to a previous version of a given file I’m allowed to do so because it keeps the old files. This works just like the database rollback function.
Next in this series
In the 2nd part of this series I’ll go into the details related to the installation and configuration of Hudson that is the continuous integration server.
Labels: .NET Framework , continuous integration , Hudson , MSBuild , repository , revision control , software engineering , svn , tools , TortoiseSVN , VisualSVN Server
Parallel LINQ (PLINQ) with Visual Studio 2010/2012 - Perf testing
On the last day of May I wrote about how to calculate prime numbers with LINQ in C#. To close that post I said that I’d use the PrimeNumbers delegate to evaluate PLINQ (Parallel LINQ) and measure the performance gains when the same calculation is done in parallel instead of in a sequential fashion.
PLINQ is LINQ executed in Parallel, that is, using as much processing power as you have in your current computer.
If you have a computer with 2 processor cores like a dual core processor you'll get your Language Integrated Query operators do the work in parallel using both cores.
Using "only" LINQ you won't get as much performance because the standard Language Integrated Query operators won't parallelize your code. That means your code will run in a serial fashion not taking advantage of all your available processor cores.
There are lots of PLINQ query operators capable of executing your code using well known parallel patterns.
After this brief introduction to PLINQ let’s get to the code.
As promised, today I show the performance gains when the PrimeNumbers delegate is run in 2 cores (parallel) instead of only 1 core (sequential).
Here’s the delegate code:
Func<int, IEnumerable<int>> PrimeNumbers = max => from i in Enumerable.Range(2, max - 1) where Enumerable.Range(2, i - 2).All(j => i % j != 0) select i;
To make it a candidate to parallelization we must just call the AsParallel() extension method on the data to enable parallelization for the query:
Func<int, IEnumerable<int>> PrimeNumbers = max => from i in Enumerable.Range(2, max - 1).AsParallel() where Enumerable.Range(2, i - 2).All(j => i % j != 0) select i;
I set up a simple test to measure the time elapsed when using the two possible ways of calling the delegate function, that is, sequentially in one core and parallelized in my two available cores (I have an Intel Pentium Dual Core E2180 @ 2.00 GHz / 2.00 GHz).
Let’s calculate the prime numbers that are less than 50000 sequentially and in parallel:
IEnumerable<int> result = PrimeNumbers(50000);
Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); foreach(int i in result) { Console.WriteLine(i); } stopWatch.Stop(); // Write time elapsed Console.WriteLine("Time elapsed: {0}", stopWatch.Elapsed);
Now the results:
1 core
Time elapsed: 00:00:06.0252929
2 cores
Time elapsed: 00:00:03.2988351
8 cores*
Time elapsed: 00:00:00.8143775
* read the Update addendum bellow
When running in parallel using the #2 cores, the result was great - almost half the time it took to run the app in a sequential fashion, that is, in only #1 core.
The whole work gets divided into two worker threads/tasks as shown in Figure 1:
Figure 1 - The Parallel Stacks window in Visual Studio 2010 ( #2 cores )
You can see that each thread is responsible for a range of values (data is partitioned among available cores). Thread 1 is evaluating the value 32983 and Thread 3 is evaluating 33073. This all occurs synchronously.
If I had a computer with 4 cores, the work would be divided into 4 threads/tasks and so on. If the time kept decreasing I’d achieve 1.5 seconds to run the app. Fantastic, isn’t it?
The new Microsoft Visual Studio 2010 (currently in Beta 2) comes with great debugging tooling for parallel applications as for example the Parallel Stacks shown in Figure 1 and the Parallel Tasks window shown in Figure 2:
Figure 2 - The Parallel Tasks window in Visual Studio 2010 ( #2 cores )
This post gives you a rapid view of PLINQ and how it can leverage the power of you current and future hardware.
The future as foreseen by hardware industry specialists is a multicore future. So why not get ready to it right now? You certainly can with PLINQ. It abstracts all the low level code to get parallel and let’s you focus on what’s important: your business domain.
If you want to go deep using PLINQ, I advise you to read Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4 by Stephen Toub.
Running this same sample app on a Intel Core i7-3720QM 2.6GHz quad-core processor (with #4 cores and #8 threads) this is the result:
Time elapsed: 00:00:00.8143775
This is on a par with the #1 core and #2 cores tests shown above. The work is being divided "almost" evenly by 8 if we compare with the first benchmark ( only #1 core ).
00:00:06.0252929 / 8 = 0.7525
Of course there’s been lots of improvements between these different processor generations. The software algorithms used to parallelize the work have also been improved (now I’m running on Visual Studio 2012 with .NET 4.5). Both hardware/software specs are higher now. Nonetheless these numbers give a good insight about the performance gains both in terms of hardware and software. Software developers like me have many reasons to celebrate!
Figure 3 - The Parallel Stacks window in Visual Studio 2012 ( #8 threads )
If I take out the .AsParallel() operator, the program runs on a single core and the time increases substantially:
Time elapsed: 00:00:03.4362160
If compared with the #4 cores benchmark above, we have:
00:00:03.4362160 / 4 = 0.8575
0.8575 – 0.8143 = 0.0432 (no difference at all)
Note: this faster processor running on a single core has a performance equivalent to the old Intel #2 core processor. Pretty interesting.
References
Features new to parallel debugging in VS 2010
Debugging Task-Based Parallel Applications in Visual Studio 2010 by Daniel Moth and Stephen Toub
Great lecture on what to expect from the multicore and parallel future…
Slides from Parallelism Tour by Stephen Toub
PLINQ documentation on MSDN
http://msdn.microsoft.com/en-us/library/dd460688%28VS.100%29.aspx
Parallel Computing Center on MSDN
http://msdn.microsoft.com/en-us/concurrency/default.aspx
Daniel Moth’s blog
http://www.danielmoth.com/Blog/index.htm
Microsoft Visual Studio 2010
http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx
Labels: .NET Framework , C# , LINQ , parallel programming , performance , PLINQ , tasks , testing , threads , Visual Studio
Introduction to the F# programming language
Yesterday after reading the post YAPES: Problem Five at Dustin Campbell's site Did it with .NET, I was motivated to download the F# compiler bits. I've been keeping track of the news related to this new programming language but still hadn't felt a strong desire to play with it. There are so many new technologies emerging that you sometimes don't know where to focus your attention. Read the post The "Driving Force" pattern--part 1 of N so that you get a glimpse of what I'm expressing here.
This time I couldn't resist and so I'm really going to study this new language. Why have I decided to do so? It's because F# is a simple yet powerful new programming language that let's you express your thinking process in a more convenient way. By looking at the solutions presented in Dustin's posts you can have a taste of the power of F#.
F# is based on principles of functional programming although it's a mix of the different flavors of programming paradigms. That's because it targets .NET Framework. This way it is a multi-paradigm programming language with concepts of imperative and object-oriented programming disciplines.
The language is being developed at Microsoft Research. The folks behind the language plans to ship it with the next version of Visual Studio according to Somasegar's post F# - A Functional Programming Language. In the near future F# will be a real citizen of the .NET family of programming languages.
To me it's a completely new experience. I'm already familiarized with the new language extensions of C# like generics, lambda expressions and anonymous functions that bring to C# some of the concepts initially developed and implemented in functional programming languages. The ones mentioned here are a few language constructs if compared to the whole gamma of new functional language constructs that I must learn. There are plenty of them that I haven't seen in practice before. I'm really excited about what I'll learn on the next days and months.
OK, after a brief story it's time to show how you can start playing around with F# too.
Download F#
Go to the F# download page and get the .msi or .zip package. You can use Windows or Linux (Mono) to develop F# programs.
The package brings the F# compiler and a F# project template and debugger to be used within Visual Studio. Yes, although F# is new it has already gotten into Visual Studio. You get a lot of cool features using VS integrated development environment. The only drawback is that you need a paid full featured version of Visual Studio. Visual Studio Express editions aren't good to go. Check why in this thread about F# with Visual Studio Express.
I searched the internet and found a solution in the case you don't have a paid version of Visual Studio and want to use the VS IDE to get type checking and debugger warnings. You can follow the instructions of the post Do it yourself: Visual F# Express 2008. Basically you'll download a Visual Studio IDE that accepts add-ins but this IDE doesn't include the other .NET language as C# and VB.NET. I didn't try it because the download is big (316 MB) if you take into account that I still use a dial-up connection.
Final notes
One of the most interesting things of working in the technology arena is the velocity in which things are developed and shipped to the market. It appears that all the research done on the 70s are becoming real products today. This is because in the past there wasn't the opportunity of breaking barriers like we have today as getting in touch with people from anywhere in the world. We didn't have access to top technologies ten years ago. After the internet everything is more democratic and that's what makes the technology field one of the best to work on. You have the possibility of spreading to the world your new discoveries and they get to reality much faster. If you haven't read Somasegar's post I linked above, do so and you'll see what I mean.
References
F# site at Microsoft Research
http://research.microsoft.com/fsharp/fsharp.aspx
Don Syme's WebLog on F# and Other Research Projects - The guy behind the curtains
http://blogs.msdn.com/dsyme
Chris Smith's completely unique view on F#, more F#, and maybe other stuff
http://blogs.msdn.com/chrsmith
Brian's random thoughts about writing code for .NET
http://lorgonblog.spaces.live.com/
Jomo Fisher -- Sharp Things
http://blogs.msdn.com/jomo_fishe
LukeH's WebLog
http://blogs.msdn.com/lukeh
Books
Expert F# by Don Syme, Adam Granicz and Antonio Cisternino
Foundations of F# by Robert Pickering
Hello World Web Site with ASP.NET MVC
Hello World
A "hello world" application prints out "Hello, world!" on the screen. It is used in many introductory tutorials for teaching a programming language or upcoming technology. Such a program is typically one of the simplest programs possible in a such language or specific technology.
ASP.NET
ASP.NET is a web application framework developed and marketed by Microsoft, that developers can use to build dynamic web sites, web applications and web services. It was first released in January 2002 with version 1.0 of the .NET Framework, and is the successor to Microsoft's Active Server Pages (ASP) technology. ASP.NET is built on the Common Language Runtime, allowing programmers to write ASP.NET code using any supported .NET language.
MVC
Model-View-Controller (MVC) is an architectural pattern used in software engineering. Successful use of the pattern isolates business logic from user interface considerations, resulting in an application where it is easier to modify either the visual appearance of the application or the underlying business rules without affecting the other. In MVC, the Model represents the information (the data) of the application and the business rules used to manipulate the data, the View corresponds to elements of the user interface such as text, checkbox items, and so forth, and the Controller manages details involving the communication to the Model of user actions such as keystrokes and mouse movements.
In detail what happens in the Model-View-Controller pattern is:
- Browser requests URL
- Route is determined
- Controller is activated
- Method on Controller is invoked
- Controller does some stuff
- Controller renders the View, passing in ViewData
Hello World Web Site
This Web Site basically displays a "Hello, [Name]" message. The variable "Name" receives the data that is passed in the URL to the HelloWorldController action method. The action method will store the URL data in the Controller's ViewData object. The ViewData object will then be used when the View is rendered. It'll be more clear after you implement the code.
Note: I'm not using database interaction (database Model), so the Model part of the MVC pattern isn't created.
I'll show you the steps I used to get an ASP.NET MVC Web Site running with Microsoft Visual Web Developer 2008 Express Edition.
It's important to note that the current version of ASP.NET MVC is the ASP.NET MVC Preview 2. This version wasn't planned to be used with Visual Web Developer Express, so it's necessary to use an adapted project template to get it going properly.
Stuff to download
In order to get the necessary software parts you should install the following if you still haven't them.
- Microsoft Visual Web Developer 2008 Express Edition
- ASP.NET MVC Preview 2
- ASP.NET 3.5 Extensions Preview
- ASP.NET MVC Project template
It's mandatory that you install all the above software to avoid erros when debugging the web site. I've run into errors just because I hadn't the ASP.NET 3.5 Extensions Preview, so do install everything.
Implementing the Hello World Web Site
Open Visual Web Developer and go to menu File - New Web Site. On the New Web Site dialog window, select your language of preference according to the ASP.NET MVC Project Template you selected above. This option can be selected on the combo box related to Language. If you don't change the language you won't see the project template. Give the Web Site the name HelloWorldMvcWebSite.
The project structure is different from the one of a Web Application that is only available on paid versions of Visual Studio Web Developer that is included in Microsoft Visual Studio Standard and Microsoft Visual Professional.
The following is the the structure you get when a new ASP.NET MVC Web Site is created:
Creating a new Controller
Let's create a new Controller called HelloWorld. To accomplish this, right-click on the file HomeController.cs and select Copy. Right-click on the folder Controls and select Paste. You'll have a new file called Copy of HomeController.cs. Right-click on this file and rename it to HelloWorldController.cs. Open this file and change its content so that it looks like the following:
public class HelloWorldController : Controller { [ControllerAction] public void HiThere() { RenderView("HelloWorld"); } }
Creating a new View
Let's create a new View that will render the data. To accomplish this, right-click on the folder Views and select New Folder. Give the new folder the name HelloWorld. Now right-click on the file Index.aspx and select Copy. Right-click on the folder HelloWorld and select Paste. You'll have a new file called Index.aspx inside the HelloWorld folder. Right-click on this file and rename it to HelloWorld.aspx. Open this file and change its content so that it looks like the following:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="HelloWorld.aspx.cs" Inherits="views_Home_Index" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title>Hello World ASP.NET MVC Application</title> </head> <body> <form id="form1" runat="server"> <div> <h1>Hello, <%= ViewData["Name"] %></h1> </div> </form> </body> </html>
Configuring the routes on the Global.asax file
The routes map the URL to the proper action method defined within the Controller.
An action method called HiThere was created inside the HelloWorldController. This method is responsible for invoking the RenderView method that then will render the View (HelloWorld.aspx).
To the above described take effect it's necessary that the proper routing (mapping rules from URLs to action methods) be configured when the application starts.
Open the file Global.asax and change its content so that it looks like the following:
<%@ Application Language="C#" %> <%@ Import Namespace="System.Web.Mvc" %> <script RunAt="server"> void Application_Start(object sender, EventArgs e) { // Code that runs on application startup RouteTable.Routes.Add(new Route { Url = "[controller]/[action]/[id]", Defaults = new { action = "HiThere", id = (string)null }, RouteHandler = typeof(MvcRouteHandler) }); RouteTable.Routes.Add(new Route { Url = "Default.aspx", Defaults = new { controller = "Home", action = "Index", id = (string)null }, RouteHandler = typeof(MvcRouteHandler) }); } void Application_End(object sender, EventArgs e) { // Code that runs on application shutdown } void Application_Error(object sender, EventArgs e) { // Code that runs when an unhandled error occurs } void Session_Start(object sender, EventArgs e) { // Code that runs when a new session is started } void Session_End(object sender, EventArgs e) { // Code that runs when a session ends. // Note: The Session_End event is raised only when the sessionstate mode // is set to InProc in the Web.config file. If session mode is set to StateServer // or SQLServer, the event is not raised. } </script> The structure of the Web Site must be like the following in the end:
Starting the debugger
Now hit F5. The Web Site will appear in a new web browser window with the following URL: http://localhost:1717/HelloWorldMvcWebSite/
A message of Welcome will be displayed since the page Index.aspx is the Start Page.
Type the following address: http://localhost:1717/HelloWorldMvcWebSite/HelloWorld/
A "Hello,", message is shown. The HelloWorld Controller is being called according to the route table defined above. The default method is HiThere with its id parameter set to null. That's why the View (HelloWorld.aspx) is showing a "Hello, " message. Since an id isn't being passed the only message shown is "Hello, ".
Typing the following address: http://localhost:1717/HelloWorldMvcWebSite/HelloWorld/HiThere/Leniel
A "Hello, Leniel" message is shown. This time the URL conforms with the route that was defined inside the Global.asax file, that is:
Url = "[controller]/[action]/[id]"
These are the assignments done when the routing system detects a URL like the one above:
controller = HelloWord action = HiThere id = Leniel
Final notes
There is no doubt that the ASP.NET MVC Framework turns the life more clean and simple.
It's always good to work in an organized environment. Separating the code related to data base interaction (Model), business logic (Controller) and Presentation/UI (View) is perfect.
Not so long ago, the programming environment was a mess wit lots of event handlers mixed with data base interactions and UI code. It was really difficult to manage all that mess. But thanks God things are getting better as it should.
Another great advantage is how the URL routing is done. It translates/conforms well to the naming scheme adopted in a given project. No more unreadable URLs that are difficult to deal with. It lends to a better searchable web site. The website will play friendly with web search crawlers.
References
To get a handful of examples I advise you to check ScottGu's blog. http://weblogs.asp.net/scottgu/archive/tags/MVC/default.aspx http://weblogs.asp.net/scottgu/archive/2007/11/13/asp-net-mvc-framework-part-1.aspx
ASP.NET MVC : The Official Microsoft ASP.NET Site
http://www.asp.net/mvc/
ASP.NET MVC - Building Web Apps without Web Forms
http://msdn.microsoft.com/en-us/magazine/cc337884.aspx
you've been HAACKED
http://haacked.com/
Visual Web Developer Web Site Project
You can get the Hello World MVC Web Site project at: http://leniel.googlepages.com/HelloWorldMvcWebSite.zip