Tuesday, March 15, 2011

Another Entity Framework 4 Repository & Unit of Work Solution–Intro and Part 2: Creating the Repositories and Unit of Work (UoW)

This is Part 2 in a series of posts that walk through the process of implementing a solution that separates concerns into specific behaviors using the Entity Framework 4 and the Repository and Unit of Work Patterns.

Below is the series outline; again, this is Part 2.
Now on to Part 2… The following download contains some T4 templates that I’ve created and/or modified from other sources.  These T4 templates will build all the code necessary to create our Domain Models, Domain Model Metadata (e.g. Data Annotations), Repositories, Services, and Unit of Work all by pointing each related T4 to the EF data model (edmx) created in Part 1 of this series. T4 Templates Download. Go ahead and download the zip file and un-compress the contents into a directory directly under the solution root.  The solution’s root directory should look something like the following, where the T4_EF4_Repository directory is the directory that contains the uncompressed files from the download. p2Solutionlist00 Open up the T4_EF4_Repository directory.  The directory should contain a ‘Source’ directory and a single PowerShell file: image The ‘Source’ directory should contain six T4 template files (*.tt) image What are these files?  Well, the files with the *.tt extension are the T4 templates that will generate the code, while the single file with the *.ps1 extension is a PowerShell script.  The following briefly describes each file:
  • Domain.Poco.tt
    • This template generates the POCO (Domain) classes from your EF data model.
  • Domain.Poco.Metadata.tt
    • This template generates data annotations/metadata ‘buddy’ classes for the POCOs.
  • Repository.Interface.tt
    • This template generates all the associated Repository Interfaces/Contracts, including:
      • base IReadOnlyRepository and  IRepository Interfaces
      • IUnitOfWork Interface
      • I<POCO_ClassName>Repository Interface for each POCO class generated from you EF data model.
  • Repository.Implementation.EF.tt
    • This template generates the EF-related concrete class implementations defined by the IRepository Interfaces/Contracts.
  • Services.Interface.tt
    • This template generates a light-weight Service Interfaces/Contracts for each POCO class.
  • Services.Implementation.tt
    • This template generates the concrete class implementation defined by the Service Interfaces/Contracts.
  • prepareT4Templates.ps1
    • This is just a simple PowerShell script that contains project-specific settings to assist in generation T4 templates specific to the project – in our scenario, the Chinook application solution.
Open up the Chinook Visual Studio Solution. We should now have a Visual Studio Solution with thee Projects (Chinook.Core, Chinook.Data.EF, Chinook.Infrastructure) and a directory located at the solution root containing the T4 templates and single PowerShell file. Open up T4_EF4_Repository directory in Windows Explorer.  Right-click the PowerShell file and select ‘Edit’ from the context menu.  image This will open up the PowerShell editor and display the content of the PowerShell file.  As you can see, this is simple script that does a find/replace, creates a new directory, and creates new T4 templates that contain the replaced settings.
#*****************************************************************
#*****************************************************************
#*********** BEGIN Template Parameters ***************************
#*****************************************************************

# path to the project's edmx data model (entity framework data model)
$edmxFilePath = "..\..\Chinook.Data.Ef\Chinook.edmx"
# the namepace name where the solution's domain models live 
$domainModelNamespace = "Chinook.Core.Domain"
# the namespace name where the solution's services will live
$serviceInterfaceNamespace = "Chinook.Core.Services"
# the namespace name where the solution's repository will live
$repositoryInterfaceNamespace = "Chinook.Core.Repository"

#*****************************************************************
#*********** END Template Parameters *****************************
#*****************************************************************

function createDirectory($directory){
New-Item $directory -type directory -force    
}

function removeDestinationFile($file){
if(Test-Path $file){ Remove-Item $file }
}

function writeout($file){
$sourceFile = "Source/" + $file
$destinationDirectory = "Solution/"    
$destinationFile = $destinationDirectory + $file

createDirectory($destinationDirectory)    
removeDestinationFile($destinationFile)

(Get-Content $sourceFile) |
Foreach-Object {$_ -replace "\[\*\*EDMX_FILE_PATH\*\*\]", $edmxFilePath} | 
Foreach-Object {$_ -replace "\[\*\*DOMAIN_MODEL_NAMESPACE\*\*\]", $domainModelNamespace} |
Foreach-Object {$_ -replace "\[\*\*SERVICE_INTERFACE_NAMESPACE\*\*]", $serviceInterfaceNamespace} |
Foreach-Object {$_ -replace "\[\*\*REPOSITORY_INTERFACE_NAMESPACE\*\*\]", $repositoryInterfaceNamespace} |
Set-Content $destinationFile
}

$files = @("Domain.Poco.tt", "Domain.Poco.Metadata.tt", "Repository.Interface.tt", "Service.Interface.tt", "Repository.Implementation.EF.tt", "Service.Implementation.tt")

foreach($file in $files){
writeout($file)
}
As I mentioned above, the PowerShell file will generate T4 templates specific to your project.  If you followed along in Part 1, these setting variables are taken from the namespaces that we specified in the last step.  If you missed it, the following table duplicates our previous efforts:
Directory Namespace
Domain Chinook.Core.Domain
Repository Chinook.Core.Repository
Services Chinook.Core.Services
The following are the project-specific settings:
  • $edmxFilePath
    • relative path to the solution’s EF data model (edmx)

  • $domainModelNamespace
    • the namespace where the solution’s POCO’s live – see namespace table above
  • $serviceInterfaceNamespace
    • the namespace where the solution’s Service Interfaces/Contracts live – see namespace table above
  • $repositoryInterfaceNamespace
    • the namespace where the solution’s Repository Interfaces/Contracts live – see namespace table above
If you followed through this post's series, there is no need to change the aforementioned settings.  They are already set to the proper solution-specific settings.  If not, go ahead and change the necessary settings. You can run the PowerShell file within the editor of by right-clicking the PowerShell file and click ‘Run with PowerShell.’  However, since we already have the file open in the editor, we are going to use the editor. Click the ‘Run’ button on the editor’s toolbar: image If when running the PowerShell file you receive the following error, you do not have the proper permission to execute PowerShell scripts:
File C:\Chinook\T4_EF4_Repository\prepareT4Templates.ps1 cannot be loaded. The file C:\Chinook\T4_EF4_Repository\prepareT4Templates.ps1 is not digitally signed. The script will not execute on the system. Please see "get-help about_signing" for more details..
You have a couple choices to get around this, but the easiest is to set the PowerShell execution policy to ‘unrestricted’ using the following PowerShell command (* you must be running PowerShell as an Administrator).  Go ahead and run this command in the PowerShell console in the bottom pane of the PowerShell editor:
Set-ExecutionPolicy UnRestricted
Accept the ‘Execution Policy Change’ dialog message – the dialog only appears if you are using the editor.  If you are using the non-editor PowerShell console, this ‘Execution Policy Change’ message will only echo to the console. Sorry about that little hiccup.  If you’re not comfortable with setting the execution policy to 'unrestricted,’ you get reverse the policy back to ‘restricted’ once you’re done generating the necessary T4 templates by using the following PowerShell command:
Set-ExecutionPolicy Restricted
For more PowerShell documentation, check out MSDN. Close the PowerShell editor. Okay, back to the tutorial…  Once you execute the PowerShell script, the T4_EF4_Repository directory will now contain a new ‘Solution’ sub-directory and will contain six T4 templates with the project-specific settings defined earlier.  These are the templates that we will be using in our application. image image Still with me?  I hope so.  I know – it’s a bit long the first time, but it’s really pretty simple and will be worth the effort.  Hang in there… Next, if you haven’t already done so, open up the Chinook Visual Studio Solution.  We are now going to add the POCO generator to the EF Data Model.  If you don’t have the ADO.NET POCO Entity Generator template installed, you will need to add it via the Visual Studio Extension Manager from the Visual Studio Gallery.

Adding the POCO Template

  • Open up the Chinook.edmx file so the EF data model is visible in the designer (this is located in the Chinook.Data.EF project)
  • Right-click on an empty area of the EF data model canvas and select ‘Add Code Generation Item…’
p2addcodegen
  • This will bring up the ‘Add new Item Dialog,’ in which you will choose the ADO.NET POCO Entity Generator template (via the Installed Templates –> Code node)
p2addpoco
  • Set the ‘Name’ of the ADO.NET POCO Entity Generator item to ‘Poco.tt’
  • Save the EF data model (edmx file) and build the Chinook.Data.EF project.
  • Delete the Poco.tt file from the Chinook.Data.EF project
    • ** DO NOT delete the Poco.Context.tt file. 

Add the T4 Templates to the Solution

We are now going to add the T4 templates that we generated earlier.
Project Directory T4 Template (Solution directory)
Chinook.Core Domain Domain.Poco.tt
Chinook.Core Domain Domain.Poco.Metadata.tt
Chinook.Core Repository Repository.Interface.tt
Chinook.Core Services Service.Interface.tt
Chinook.Data.EF * add using Project node * Repository.Implementation.EF.tt
Chinook.Infrastructure Services Service.Implementation.tt
For each one of the following directories in the list above, add the associated T4 template in listed order by right-clicking the respective directory, clicking ‘Add / Existing Item…’, navigating to the T4_EF4_Repository/Solution directory (in the root of the solution) and selecting the associated T4 template.  A couple of notes…
  • You may need to use the ‘All File(*.*)’ filter on the ‘Add Existing Item’ dialog.
  • Ensure that you select the proper T4 templates  (e.g. use the ‘Solution’ directory and NOT the ‘Source’ directory)
image image

Build the Solution and Resolve Dependencies

Now, go ahead and build the solution and resolve any dependencies that appear in the Error List.  You will get errors on the ‘ObjectContext’ derived class (ChinookEntities in our scenario).  To resolve these errors, you will need to add a reference to the Domain namespace where the POCOs classes live (we identified this earlier in the ‘namespace’ table).  In our scenario, just add the following using statement to the ‘ChinookEntities’ class…
using Chinook.Core.Domain;
Build the solution again.  All the dependencies should now be resolved and the solution should build with no errors. In summary, we walked through the process of implementing a solution that separates concerns into specific behaviors using the Entity Framework 4 and the Repository and Unit of Work Patterns using T4 templates to generate the code using our EF data model

In the next post in this series, we will review a few of the generated class/interfaces that the T4 code generation templates created.

Thanks for reading…

Thursday, March 10, 2011

Another Entity Framework 4 Repository & Unit of Work Solution–Intro and Part 1: Setup

Entity Framework Code First (EF Code First) has been getting quite a bit of press lately.  I’ve done some ‘play’ development using EF Code First; however, the powers that be seem to keep bringing me back to the Model First (create database/ERD and then the application code) paradigm.

What I really like about EF Code First is the seamless use of Separation of Concerns.  My next few posts are going to be a series of entries on using the Model First approach to take advantage of Separation of Concerns.

Rather than discuss software development and design theory, these posts will walk through the process of implementing a solution that separates concerns into specific behaviors using the Entity Framework 4 and the Repository and Unit of Work Patterns.  To facilitate this process, we will be using T4 templates.

While there are many solutions online that create similar implementations, this series will focus on a process that I really like, fits my needs, and is easy to understand.  That last point is important – ‘easy to understand.’  Separation of Concerns and all the concepts that come along with it can be very overwhelming if you’re coming from ASP.NET Web Forms…

Forewarning – this series of posts contain quite a few steps.  I considered creating a NuGet package; however, I couldn’t settle on the structure of the package and I realized that I started losing focus on the intent of my madness.  I also considered creating a few Visual Studio templates; however, my experience with VS templates is limited, and once again the madness had me losing focus.  That said, hopefully this series and the steps involved will not be too overwhelming.  I feel the value of the final results far exceed the steps involved in getting there… 

UPDATE: the NuGet team is considering adding functionality where NuGet could be run from PowerShell outside of Visual Studio. This means that one could create a NuGet package that would create a solution with x number of projects and add dependencies to those projects, files, etc…  If that functionality was available now, I could deploy all the steps involved here in a single NuGet package – eliminating MOST of the steps on this series.  If this sounds cool – it is cool – vote for this functionality here.

Okay, so here is the series breakdown:
Lets get started…

Part 1: Setup

As stated above, in Part 1 we are going to create a database, create a Visual Studio solution and project structure, and generate an EF4 data model that points to our database.

1) Create a database

For this series, we are going to use the Chinook database.  Specifically, we are going to use the Chinook version 1.2 for SQL Server.  You can download the Chinook database from CodePlex – make sure you download version 1.2 – in preparing for this series, I had issues generating EF4 Navigation Properties with Chinook version 1.3, so please use version 1.2. The download contains two SQL scripts for generating the Chinook database.  Please use the SQL Script that generates table primary keys with IDENTITY. Once the Chinook database is generated, the database should similar to the following screenshot from SQL Server Management Studio (SSMS): ChinookSsms

2) Visual Studio Solution and Project Structure

The solution and related projects architecture that we are going to use loosely follows the Onion Architecture Pattern – this is a great read and well worth the time…
  1. Create an empty Visual Studio Solution.
    • Open Visual Studio
    • Click ‘File’ –> ‘New’ –> ‘Project’
    • Under the ‘Installed Templates,’ select the ‘Other Project Types’ node in the project tree, select the ‘Visual Studio Solutions’ node, and then select the ‘Blank Solution.’  Name the solution ‘Chinook.’  Here’s a screenshot of the New Project Wizard:
      solutionwizard
  2. Create the following three Class Library Projects.  Delete the auto-generated ‘Class1.cs’ file that was added to each project.
    • Chinook.Core
      • See details in the next step
    • Chinook.Data.EF
      • This is where the Repository Implementations and Unit of Work classes will live.
    • Chinook.Infrastructure
      • This is where the Service Implementations will live.
  3. Create the following three directories within the Chinook.Core Project:
    • Domain
      • This is where the Domain Model object will live.
    • Repository
      • This is where the Repository Contracts will live.
    • Services
      • This is where the Service Contracts will live
  4. Create the following directory within the Chinook.Infrastructure Project:
    • Services
At this point, the Chinook Solution should look similar to the following screenshot: solutionShot00

3) Generate an EF4 Data Model from an Existing Database

Right-click the Chinook.Data.EF Project and select ‘Add / New Item…’ efmWizard00 Next, select ADO.NET Entity Data Model from the Data Templates list, name it ‘Chinook,’ and click ‘Add’ efmWizard01 Next, select ‘Generate from database’ and click ‘Next’ efmWizard02 Now it’s time to point the EF Data Model to the Chinook database created in step ‘1) Create a Database.’  Go ahead and locate your database (or create a New Connection) and make sure that it is selected in the database drop-down-list.  Also, click the ‘Save entity connection settings in App.Config as:’ checkbox and leave the default Connection settings name.  Next click ‘Next.’ efmWizard03 Next, choose the database object that you want to model.  For this series, just choose the ‘Table’ objects by selecting the checkbox next to the ‘Tables’ node.  Click both of the checkbox options and the default Model Namespace and click ‘Finish.’ efmWizard04 The result is the EF data model that points to the 'Chinook’ database – Chinook.edmx efmWizard05 Save the file and build the Chinook Solution. A few more steps before we wrap Part 1 up…
  1. Add a reference to the ‘System.ComponentModel.DataAnnotations’ assembly to the Chinook.Core project.
  2. Add a reference to the Chinook.Core project to the other two projects: Chinook.Data.EF and Chinook.Infrastructure
  3. Make note of the namespaces of the following three directories within the Chinook.Core project – you will need these for Part 2 of the series
Directory Namespace
Domain Chinook.Core.Domain
Repository Chinook.Core.Repository
Services Chinook.Core.Services
In summary, we’ve created a new database, created a new Visual Studio application solution and project structure, and generated an Entity Framework data model from an existing database.

In the next post in this series, we’ll walk though the steps of creating Plain Old CLR Objects (POCOs) Repositories, Services, and a Unit of Work (UoW) using some T4 templates to generate all the aforementioned code.

Thanks for reading…

Tuesday, February 22, 2011

How I NuGet - Creating a NuGet Package–Without a batch file

This is a follow-up to a previous post How I NuGet – Creating a NuGet Package where I used a batch file to create my NuGet package.

The batch file is not a necessary step in the process – it’s just a preference of mine.  However, after refactoring the process to use the NuGet native commands to include files, I’m leaning toward eliminating the batch step in my process.  Recall the following high-level outline of the steps used to create the NuGet package from the previous post:
  1. Download the NuGet Command Line tool
  2. Create a generic nuget nuspec file - the nuget manifest file
  3. Update the nuget manifest with project specific settings
  4. Create a batch file (.bat) file that will serve as the main entry point into the nuget package creation process
  5. Create the nuget package
  6. Submit and contribute the package to the NuGet Gallery
Eliminating step 4, creation of the batch file and updating step 3, Update the NuGet manifest settings to the following:

<?xml version="1.0"?>
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
        <id>MvcContrib.Shp</id>
        <version>1.0.0.0</version>
        <authors>Dan Ryan</authors>
        <owners>Dan Ryan</owners>
        <licenseUrl>http://mvcxgridmenu.codeplex.com/license</licenseUrl>
        <projectUrl>http://mvcxgridmenu.codeplex.com/</projectUrl>        
        <requireLicenseAcceptance>false</requireLicenseAcceptance>        
        <description>UI Extensions to the MvcContrib Project - Themed Grid & Menu</description>
        <tags>MVC MVC3 ASP.NET MvcContrib</tags>
        <dependencies>
            <dependency id="MicrosoftWebMvc" version="2.0" />
            <dependency id="MvcContrib.Mvc3-ci" version="3.0.57.0" />
        </dependencies>
    </metadata>
    <files>
        <file src="..\src\MvcContrib.Shp\MvcContrib.Shp\bin\Release\MvcContrib.Shp.dll" target="lib" />
        <file src="..\src\MvcContrib.Shp\Shp.Web\Scripts\jquery.mvccontrib*.*" target="content\Scripts" />
        <file src="..\src\MvcContrib.Shp\Shp.Web\Scripts\superfish.js" target="content\Scripts" />
        <file src="..\src\MvcContrib.Shp\Shp.Web\Scripts\*jquery.hoverIntent*" target="content\Scripts" />
    </files>
</package>

The XML files element in the snippet above will include the child file elements in the NuGet package and place the respective file in the associated target (destination directory) of the NuGet package – the snippet above uses targets of lib and content.  You can read all above the files element and other NuGet file specifications here: .nuspec File Format

Again, this is an alternative (and recommended) way to create a NuGet package.  All the other steps in the high-level outline of steps (above) remains the same.

Thanks for reading…

Monday, February 21, 2011

How I NuGet - Creating a NuGet Package


Update: How I NuGet - Creating a NuGet Package – Without a batch file

I started toying around with the MvcContrib project a couple of months ago.  Since then, I created a few UI extensions that use the MvcContrib project. I wanted to contribute to the project; however, Jeremy Skinner recommended that I create a NuGet package and distribute my contributions that way.  So, that's what I did and this post describes/outlines the steps I used to create the NuGet package.

The source for the MvcContrib UI extensions suggested above is available on CodePlex here: MvcContrib UI Extensions - Themed Grid & Menu

My assumption is that you are familiar with NuGet.  If not, you can read all about it at its CodePlex project site.

Here is a high level outline of the steps that I used to create my NuGet package:
  1. Download the NuGet Command Line tool
  2. Create a generic nuget nuspec file - the nuget manifest file
  3. Update the nuget manifest with project specific settings
  4. Create a batch file (.bat) file that will serve as the main entry point into the nuget package creation process
  5. Create the nuget package
  6. Submit and contribute the package to the NuGet Gallery
For reference, the following is a snippet of my directory structure used in the MvcContrib UI Extensions.  I will reference this structure in the steps below.  This image will also help with understanding the batch file used in the steps below.

 

1. Dowload the NuGet Command Line tool

Easy - download the NuGet command line tool here.  Using our structure above, put the .exe into the MvcContrib.Shp/nuspec/ directory.

2. Create a generic nuget nuspec file - the nuget manifest file

Create the .nuspec file by running the following command from the dos prompt:

nuget spec
This will create a file by with the name of Package.nuspec. All this is is an xml file that describes the details of the package - formally called a package manifest or specification.  While renaming this file is not required, I think it makes sense to give it the same name as that of the resulting NuGet package  - in our scenario, MvcContrib.Shp.nuspec.

3. Update the nuget manifest with project specific settings

The NuGet .nuspec file format specification contains many configuration details; however, for our scenario I’ve updated the .nuspec file to contain the following content:

<?xml version="1.0"?>
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
        <id>MvcContrib.Shp</id>
        <version>1.0.0.0</version>
        <authors>Dan Ryan</authors>
        <owners>Dan Ryan</owners>
        <licenseUrl>http://mvcxgridmenu.codeplex.com/license</licenseUrl>
        <projectUrl>http://mvcxgridmenu.codeplex.com/</projectUrl>        
        <requireLicenseAcceptance>false</requireLicenseAcceptance>        
        <description>UI Extensions to the MvcContrib Project - Themed Grid & Menu</description>
        <tags>MVC MVC3 ASP.NET MvcContrib</tags>
        <dependencies>
            <dependency id="MicrosoftWebMvc" version="2.0" />
            <dependency id="MvcContrib.Mvc3-ci" version="3.0.57.0" />
        </dependencies>
    </metadata>
</package>
The XML elements are pretty self-explanatory; however, I recommend reading the NuGet .nuspec file format specification for details on each element.

4. Create a batch file (.bat) that will serve as the main entry point into the nuget package creation process

This step is not necessary; however, I like batch files.  Batch files give us the ability to place simple, repeatable logic into a batch file and execute that logic by double-clicking the batch file.  The following batch file creates a temp directory with subdirectories for the NuGet package content, copies the files (.dll, and .js files) from the source directories and places these files in the temp content directories, executes the NuGet.exe pack command, and then cleans up by removing the temp directories.  Again, this could have all been done via the .nuspec file, but I just prefer to use the batch.  Here’s the batch file contents:

echo OFF :: root nuspec directory set rootDirectory=%cd% ::::::::::::::::::::::::::::::::: :: 1) build the destination directory structure ::::::::::::::::::::::::::::::::: :: destination structure set baseDirectory=basenuspec set contentDirectory=content set libDirectory=lib set scriptsDirectory=Scripts :: make directory command set makeDirectoryCommand=MKDIR :: delete directory command ::set deleteDirectoryCommand=DEL /f set deleteDirectoryCommand=RMDIR /s /q :: delete the previous package build files and directories - if they were not deleted before %deleteDirectoryCommand% %baseDirectory% :: build the directory structure %makeDirectoryCommand% %baseDirectory% cd %baseDirectory% %makeDirectoryCommand% %libDirectory% %makeDirectoryCommand% %contentDirectory% cd %contentDirectory% %makeDirectoryCommand% %scriptsDirectory% :: navigate to the root directory cd %rootDirectory% ::::::::::::::::::::::::::::::::: :: 2) copy files from source to destination ::::::::::::::::::::::::::::::::: :: relative path to the MvcContrib.Shp.dll set srcLibDirectory=..\src\MvcContrib.Shp\MvcContrib.Shp\bin\Release\ :: relative path to source script files set srcScriptsDirectory=..\src\MvcContrib.Shp\Shp.Web\Scripts\ :: lib files to copy set libFiles=MvcContrib.Shp.dll :: script files to copy set scriptFiles=jquery.mvccontrib*.* superfish.js *jquery.hoverIntent* :: copy commnad set copyCommand=COPY /y :: copy the source dll to the lib destination directory %copyCommand% %srcLibDirectory%\%libFiles% %rootDirectory%\%baseDirectory%\%libDirectory%\ :: navigate to the root directory cd %rootDirectory% :: navigate to the source scripts directory cd %srcScriptsDirectory% :: copy the source scripts to the scripts destination directory for %%F in (%scriptFiles%) do %copyCommand% %%F %rootDirectory%\%baseDirectory%\%contentDirectory%\%scriptsDirectory%\ :: navigate to the root directory cd %rootDirectory% ::::::::::::::::::::::::::::::::: :: 3) create the nuget package ::::::::::::::::::::::::::::::::: :: nuget pack command set packCommand=NuGet.exe pack :: nuspec manifest file set manifest=MvcContrib.Shp.nuspec :: run the nuget package command %packCommand% %manifest% -b %baseDirectory% :: delete the temp package build files and directories %deleteDirectoryCommand% %baseDirectory% ::PAUSE
The above batch file is pretty much fully documented, so it shouldn’t take too much to understand the logic.

Could I have used PowerShell to do this? Absolutely; however, I really haven't spent much time diving into PowerShell. Until then, the batch solution works just fine.

As a side note - NuGet gives you the ability to add Content to the package (this is essentially what the previous batch file is doing); add pre-processing of files to the client project (the project importing the NuGet package); add XML elements to be merged with the client project's .config files; add PowerShell scripts to do anything else that the NuGet package requires; and a whole laundry list of other functionality. Again, if you're interested, check out the NuGet Project and Documentation on CodePlex.

5. Create the nuget package

In our scenario, creating the NuGet package is simple.  All you have to do is double-click the .bat file and the batch file handles the command to create the NuGet package.  The resulting package is compiled into a single file.  In our scenario and using the .nuspec file from above, the resulting package is compiled into: MvcContrib.Shp.1.0.0.0.nupkg. How is the package name composed? The following image identifies the package name components:

nupkgname

 

6. Submit and contribute the package to the NuGet Gallery

Log into the NuGet Gallery and contribute your package.  What?  If you don’t already have an account, request one from the NuGet Gallery.  The process of submitting/contributing you package for distribution is as simple as uploading and following the NuGet package wizard.

Useful Links:
Anyway, thanks for reading…

Monday, February 7, 2011

MvcContrib Menu

Demo | Source

This page is a placeholder for now; however, I intent to create a post that describes the use of my own version of the MvcContrib Menu Helper.

For now, you can see a working demo by using the demo link.  Once I have the source code cleaned up a bit, I'll post the source code.

Below is a quick snippet of the code used to generate the main menu in the demo. Notice the fluent style and the use of Razor Templates. BTW, sorry for the poor color-code - Razor doesn't format well using SyntaxHighligher.

@Html.MvcContrib().Menu().Items(menu => {
    menu.Action<HomeController>(c => c.Index(), "no text displayed", Url.Content("~/Content/ico/house.png"))
        .ItemAttributes(@class => "solo").DisplayText(false); 
           
    menu.Link("About", null, Url.Content("~/Content/ico/application_side_boxes.png")).Items(sub => {
        sub.Content(
            @:@Html.Partial("_MvcContribLogo")    
        );
    }).ListAttributes(style => "width: 450px;", @class => "sf-shadow-off");
    
    menu.Link("Secure", null, Url.Content("~/Content/ico/lock_open.png")).Items(sub => {
        sub.Secure<HomeController>(c => c.Index(), null, Url.Content("~/Content/ico/application_view_tile.png"));
        sub.Secure<HomeController>(c => c.About(), null, Url.Content("~/Content/ico/info2.png"));
        sub.Secure<HomeController>(c => c.SecurePageOne(), null, Url.Content("~/Content/ico/shield.png"));
        sub.Secure<HomeController>(c => c.SecurePageTwo(), null, Url.Content("~/Content/ico/shield_go.png"));
    });
    
    menu.Link("Insecure", null, Url.Content("~/Content/ico/lock.png")).Items(sub => {
        sub.Action<HomeController>(c => c.Index(), null, Url.Content("~/Content/ico/application_view_tile.png"));
        sub.Action<HomeController>(c => c.About(), null, Url.Content("~/Content/ico/info2.png"));
        sub.Action<HomeController>(c => c.SecurePageOne(), null, Url.Content("~/Content/ico/shield.png"));
        sub.Action<HomeController>(c => c.SecurePageTwo(), null, Url.Content("~/Content/ico/shield_go.png"));
    });
    
    menu.Action<MenuController>(c => c.Index(), "Menu Examples", Url.Content("~/Content/ico/house_go.png"));
})

Demo | Source

Friday, January 21, 2011

jQuery Input Button Plugin - Iconizes Submit and Reset Buttons

Demo | Source

Last week I wrote a post on jQuery UI Buttons using Custom Icons. As I was testing the functionality, I felt that the jQuery UI Button widget was missing something - the ability to add icons to Submit and Reset buttons. So, I rolled my own plugin.

This plugin enables adding icons to Submit and Result buttons. Behind the scenes, the plugin replaces the Submit and Reset buttons with standard button elements and then delegates the rest to the jQuery UI Button widget.

This plugin can be used just like the jQuery UI Button widget, the only difference is the function that is invoked on the selector.

To use the plugin, you need to reference all the required jQuery UI Button widget resources and add a reference to the jquery.inputButton.js script file (available in the source download).  Then you would replace the jQuery UI Button widget function attached to your selector with the inputButton function.  That's quite a mouthfull, so here's a snippet.

$(function(){   
    // this will not add icons to your buttons - it will only stylize the buttons         
    $("input:submit:first").button({ icons: { primary: "ui-icon-disk"} });
    $("input:reset:first").button({ icons: { primary: "ui-icon-refresh"} });

    // this will add icons and stylize your submit and reset buttons
    $("input:submit:first").inputButton({ icons: { primary: "ui-icon-disk"} });
    $("input:reset:first").inputButton({ icons: { primary: "ui-icon-refresh"} });
});

Other than that, the plugin is identical to that of the jQuery UI Button widget.

A few things to keep in mind:
  • This is a proof of concept. I've tested with Chrome, Firefox, and IE 8 and it works as intended and designed.
  • Once the inputButton plugin is executed, the Submit and Reset buttons are now Button elements; therefore, all code that manipulates elements filtered on the button element (e.g. $("button")) will include the transformed Submit and Reset buttons.
  • If neither a Submit nor a Reset button is passed as the selector, the selector is passed along to the jQuery UI Button widget - meaning the selector is handled just like any other selector by the jQuery UI Button widget.

Okay, that's about it. Thanks for reading..

Demo | Source

Friday, January 14, 2011

jQuery UI Buttons using Custom Icons

Demo | Source

Everything jQuery rocks!

jQuery makes JavaScript development enjoyable.  jQuery UI gives us common functional components that are easy to configure and even easier to plug into our applications.  jQuery UI Themes gives us the ability to stylize our applications using easy to learn conventions; furthermore, jQuery UI trivializes theme switching.

So why do we need to customized our jQuery button icons?  The truth is is that we probably don't; however, I tend to find myself wanting more when it comes to out-of-the-box jQuery icons.

Awhile back, I created a project on CodePlex for ASP.NET Web Forms called Iconized Control Set.  You can read about it here, download the bits here, and demo it here.  The following is the description from CodePlex: "ASP.NET WebForms IconizedButton Custom Control Set. Replaces the dull Button/LinkButton/HyperLink controls with styling and left and right aligned icons (via FamFamFam icon set). Contains built-in control styles/skins. Available customized user-configured styles/skins via CSS."

I wanted something similar to my Iconized Control Set, yet I wanted to use it for raw HTML and possibly for ASP.NET MVC.  While I plan on creating an MVC HTML Helper to abstract the details, I'm not quite ready to go down that road; however, the code here will help me create the MVC HTML Helper in due time.

While I consider this a proof-of-concept, I've tested the output in FireFox, Chrome, and IE 8 and it appears to working just fine.

In building the custom icon functionality for the jQuery Button, I once again relied on the excellent FamFamFam icon set.  The FamFamFam icon set is not a requirement to use this customization implementation; however, I find that the FamFamFam icon set gives me what I need and then some.  That said, you can certainly create your own classes and use any icons that you desire.

Okay, enough background and introduction stuff....  On to the demo...

Take a look at the demo here.

Beyond the standard jQuery imports and configuration, you will need the resources located in the code download here.  Once you have you jQuery import and configuration set up, you will need to add the following two CSS imports to your page:

<link type="text/css" href="assets/css/fff.icon.core.css" rel="stylesheet"/>
<link type="text/css" href="assets/css/fff.icon.icons.css" rel="stylesheet"/>

Once you have that, all you need to do is pass your custom icon class to the button widget function in the standard jQuery button widget implementation:

$(function(){            
    $(".nav a").button({icons: {primary: "fff-icon-house-go"}});                  
});

Note.  The demo and download both have all the custom CSS classes in one file.  While this makes a demo like this easy, this file is big and is not recommended in production.  Extract the icon classes that your application uses and put those classes into one of your application stylesheets.

Okay, that's about it. Thanks for reading...