Tips & Tricks
Tips and tricks to help improve productivity
Modify Visual Studio 2012 Dark/Light Shell Themes

UPDATE: 9/7/2012 - An "official" theme editor for VS2012 is now available in the VS extension gallery available here:
http://visualstudiogallery.msdn.microsoft.com/366ad100-0003-4c9a-81a8-337d4e7ace05
The remainder of this post is for archival purposes and is out-dated.

imageSo, Visual Studio 2012 is nice but I ran into some serious usability issues. I like the dark theme, but it was too dark. Something between light and dark would have been perfect.

In my current setup:

  • I turn down my monitor's contrast to the lowest setting.
  • I turn down my Nvidia driver contrast down to the lowest setting.

I spend a lot of time on the computer so it is important to  keep these settings where they are. I don't want fiddle with these nobs back and forth just to use Visual Studio.

After some research and play, I found where Visual Studio 2012 was storing and reading theme / color data. Specifically here:

HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0_Config\Themes

Notice, there's a Data value in each sub-key category. This Data value is binary-byte packed with color values and color names. I wrote a small tool that that reads Data for each category and allows you to inject your own colors.

image

 

Visual Studio 2012 Theme Editor

Play it safe: Please backup your registry before using this. You can backup your current theme by using the green "Backup Theme to File" button.

Visual Studio 2012 Themes


Visual Studio 2012 Icon Patcher



FAQ

  • Can I change the ALL CAPS menu?
    Yes,
       1. Close Visual Studio
       2. Launch regedit and navigate to
         HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0\General 
       3. Create a DWORD value named SuppressUppercaseConversion with value 1.
    That should suppress the upper casing on the FILE, EDIT, VIEW menu area in Visual Studio 2012.
  • Can I change the Visual Studio 2012 Icons?
    Yes, See the link above: http://vsip.codeplex.com/
  • I changed a color, it doesn't work. What's wrong?
    Keep trying. There's hundreds of colors VS uses so it might take some time to find the color you're trying to modify. Most of Visual Studio's Shell colors are in the Environment category - take a look in there. Also, keep in mind, Visual Studio uses many colors, and sometimes colors get "brushed over" others.
  • How do I reset my theme?
    Click on the Reset Theme link in the main program to go back to stock colors.
  • There's a bug in your program. Can you fix it?
    Probably. I didn't spend much time creating a bulletproof UI. I just needed something quick to hack these color values. Since it's open-source, feel free to fork, download, fix, and push me a patch.
     

For me, some important colors that I needed to adjust:

  • Environment > CommandBarMenuBorder
  • Environment > CommandBarMenuBackgroundGradient(Start/End)
  • Environment > CommandBarMenuItemMouseOver

 

Hope that helps, happy coding! 
Brian Chavez

22 Comments Filed Under [ Tips & Tricks ]
How to save the start up location of RDP/RDC window

The Problem

I like using RDP but I get very frustrated when the terminal window doesn’t remember the location.

Evert time I connect via RDP, the remote window starts in the top-left corner of my primary screen. It drives me nuts.

In this post, I’ll explain how to save the location of the window without hacking RDP files.

 

Set The Defaults

Run MSTSC:

image41

 

Next, adjust your desired settings in General, Display, and Local Resources….

image12 

 

Click Save button, DO NOT CONNECT, and Close MSTSC when done.

image18

Essentially, what we’ve done is save these connection preferences to “Default.RDP” (see details at the end of this post).

 

Place The Window

Next connect to the machine using the /v: switch:

image25

 

Move, place, resize, and adjust the terminal window where you want MSTSC to start every time.

image4

NOTE: If you want scrollbars to be removed adjust the height and width of the window now. You may need to click the restore button between the close and minimize button on the top right.

 

Next, Close the terminal window when you’re done and click OK.

image29

MSTSC should now save the last position of the window in “Default.RDP” (see details at the end of this post).

 

Save The RDP file

Run MSTSC again:

image33

Now Click SAVE AS..:

image37

Double click on your new RDP file.

Your new terminal window should start  at the same position every time you double click on your new RDP file.

 

The Details: The Default Settings File

MSTSC stores default connection preferences in a hidden file called “Default.rdp” located in:

[System.Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments)
# Windows 7: %USERPROFILE%\Documents\Default.rdp
# Windows 2000 / XP: %USERPROFILE%\My Documents

Note: If you don’t see Default.rdp, you’ll need to turn on “Show Hidden Files”.

Default.rdp is the default settings (& window state location) for MSTSC.

Brian Chavez

One Comment Filed Under [ Tips & Tricks ]
How to Setup a Windows 2008 R2 SNTP/NTP Server

Gee, setting up an SNTP/NTP server in Windows is not intuitive.

The good news is: When configured correctly, you can use the Windows Time (W32Time) service as an SNTP/NTP server for both windows and non-windows SNTP/NTP clients.

Here's how to do it:

  1. Click Start, click Run, type regedit, and then click OK.
  2. Locate and then click the following registry entry:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config\

  3. In the right pane, right-click AnnounceFlags, and then click Modify.
  4. In the Edit DWORD Value dialog box, under Value data, type 5, and then click OK.
  5. Enable NTPServer.
    1. Locate and then click the following registry subkey:

      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
                                                      Services\W32Time\TimeProviders\NtpServer\

    2. In the right pane, right-click Enabled, and then click Modify.
    3. In the Edit DWORD Value dialog box, type 1 under Value data, and then click OK.
  6. Exit Registry Editor.
  7. At the command prompt, type the following command to restart the Windows Time service, and then press ENTER:

    net stop w32time && net start w32time

This should get you setup with minimal registry hack impact.

Tips

  • Make sure W32Time is set to Automatic startup mode.
  • Make sure UDP 123 is allowed through your firewall.
  • Use this InternetTime program to help you debug connectivity to your SNTP/NTP server.

Hope that helps,
Brian Chavez
34 Comments Filed Under [ Tips & Tricks ]
Upgrading SubText, IIS7, Windows 2008

image Bit Armory, Inc. has decided to finally make the move to IIS7 for production.  Let's hope it goes well.

 

First Impressions:

  • Performance seems a little better
  • Better ASP.NET MVC support
  • Easier Setup

I did have a problem with Subtext and IIS 7 yelping back an error:

"System.Web.HttpException: Request is not available in this context"

Thanks to Lance Fisher, the fix was easy, simply set "Classic .NET AppPool" in Manage Web Site > Advanced Settings ... should do the trick.

image

 

Hope that helps!

Brian Chavez

Add Comment Filed Under [ Tips & Tricks Errors ]
Enterprise Library Validation MessageTemplate Tokens

I always forget... pulled from MSDN with my notes added in italics:

Understanding Message Template Tokens

Custom message templates can contain tokens. The validator replaces these tokens with values before it adds the resulting message to an instance of the ValidationResult class. Tokens are represented by using the strings {0}, {1}, {2}, and so on within the message template strings. All validators provided by the Validation Application Block use the first three tokens {0}, {1}, and {2} for the same purposes. Different validators may also understand additional tokens, beginning with {3}. The following table describes tokens {0}, {1}, and {2}.

Token

Description

{0}

This token represents the value of the object that is being validated. Although it can be useful to show the original value as a part of the validation message, you must be careful to avoid injection attacks by escaping any characters that can be used to attack the system that conveys the message to the user.

In simple terms: returns "ObjectBeingValidatedFullTypeName+Field"

{1}

This token represents the key of the object that is being validated. When the validator is attached to a member of a type such as a property or a field, the key is set to the member name. When the validator is attached to an object, the key is null and the token is replaced by an empty string.

In simple terms: returns "Field" name being validated

{2}

This token represents the tag that is specified on the validator instance. If no tag is supplied, the token is replaced by an empty string.

In simple terms: returns contents of [Validator Tag="foo"] property defined in the attribute.

Add Comment Filed Under [ Tips & Tricks C# ]
Fluent C Sharp Language Extension Helpers - Part 1

So, I found myself doing a lot of for( int i = 0; i < n; i++ ){} stuff lately.  So, I've decided to try something new. I've started a small collection of "Fluent Helpers" that alleviate a lot of the verbosity in C#.

About 28 characters (including spaces) for a simple for loop to do some constant iteration.

for( int i = 0; i < n, i++){

About 18 characters to do this (no pun intended):

Do.This( 5, () =>{

Here's an example:

   51             Do.This( 5,

   52                     () =>

   53                         {

   54                             Console.Write( "Hello " );

   55                             Console.WriteLine( "World!" );

   56                         }

   57                 );

Prints:

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!

Now that feels much better on my hands, and looks much cleaner too, IMHO.  Here's the simple implementation for Do.This:

   42     public static class Do

   43     {

   44         public static void This(int times, Action what)

   45         {

   46             for( int i = 0; i < times; i++ )

   47             {

   48                 what();

   49             }

   50         }

   51     }

I've already started a little library of these small syntax helpers I've collected.  If you have any suggestions, please share! cool0003.gif

-Brian Chavez

Add Comment Filed Under [ Tips & Tricks C# ]
Understanding ScriptResource and WebResource in ASP.NET

Here are some common questions about ASP.NET and web resources:

  • What is a web resource?
  • How do I get my embedded scripts to be delivered by ScriptResource.axd handler?
  • How do I get my embedded scripts to be delivered by WebResource.axd handler?
  • What is the difference between ScriptResource.axd and WebResource.axd?

First, let's tackle the first question.  What is a web resource and why would you use such a thing?

Web Resources

A web resource is a file embedded in an assembly.  This file can either be a JavaScript file or a BMP, or any other emendable type of resource in an assembly.  Just take a look at System.Web and all the embedded resources that are defined:

image

You'll notice there are both, Images and Scripts.  There's even some html!  So, web resources (at an assembly level) can be composed of just about anything you want.

How do you define Web Resources?

Meet the [WebResource] attribute.  You define web resources by using the WebResource attribute.  The WebResourceAttribute acts as an access marker to allow resource handlers to find your resources.  The first parameter to WebResource is the name of the web resource, the second parameter is the ContentType.

[WebResource(
  webResourceName
    Type: System.String
    The name of the of Web resource.
,
  contentType
    Type: System.String
    The type of resource, such as "image/gif" or "text/javascript".
)]

image Once you have your [WebResource] defined in your assembly, the next step is to mark the file you want embedded as an "Embedded Resource" in Visual Studio.

 

 

 

Working with Assembly Resources

There are two basic ways to getting at your assembly resources loaded on your ASP.NET web page.  ScriptResource.axd and WebResource.axd.

Using WebResource.axd

Generally, you'll want to use WebResource.axd when you are dealing with binary resources.  Things like emendable images or other types of media.  You can use WebResource for serving out JavaScript files but there is a better alternative.  However, if you're stuck in ASP.NET 2.0 land with out Microsoft AJAX, then WebResource.axd is your only option to serve out your embedded assembly resources.  To make your assembly resources available on your ASP.NET page, simply use:

  104  //Uses WebResource.axd

  105  this.Page.ClientScript.RegisterClientScriptResource(

  106     typeof(SwfObject), "ProjectBase.Web.Scripts.swfobject.js" );

  107 

  108  string urlToFunnyWebResourceUrl =

  109     this.Page.ClientScript.GetWebResourceUrl(

  110     typeof(SwfObject), "ProjectBase.Web.Images.Header.gif" );

urlToFunnyWebResourceUrl is the the actual absolute path to your webresource.  So you could potentially use it to link to an image or script.  ClientScript.Register* are generally reserved for loading JavaScript.  It's pretty straight forward, pass in the typeof(Control) that's requesting the resource, and the full name to the assembly resource.  The result of these calls will generate URLs to WebResource.axd.

Using ScriptResource.axd

As I mentioned earlier, there is a better alternative for loading your JavaScript assets if you're working with ASP.NET AJAX.  Using ScriptResource.axd handler actually has some interesting features.  Some features include:

  • Automatically GZip/Compressing your scripts over HTTP for delivery.
  • Dynamically resolving Release/Debug scripts based on build parameters.  This is useful, if you keep two types of the same script: one for debug, and one packed for release.
  • Can be used for Non-MsAJAX Framework script assets such as jQuery.

The ScriptManager object is how we can get our embedded JavaScript into our page using ScriptResource.axd:

  112  //Uses ScriptManager.axd

  113  ScriptManager.RegisterClientScriptResource(

  114     this, typeof(SwfObject), "ProjectBase.Web.Scripts.swfobject.js" );

The calling semantics are pretty much the same as the previous calls to WebResource.axd, the only difference is that we are passing in this instance of the control that wants to register the script.  The effect of calling this method results in scripts being loaded from ScriptResource.axd.

That's it!  Happy coding!  I'll probably add some more tips on this post if I come across any.

Brian Chavez

The ParseChildren PersistChildren and PersistenceMode.InnerProperty

After a while of non-web control development, ParseChildren and PersistChildren attributes are important attributes to remember when trying to get the desired results your looking for in the Visual Studio designer.

So, this post should clear up (and serve as a reminder for me) how and why these attributes are important.  Let's explore what these two attributes are used for.  Let's start with ParseChildren.

The [ParseChildrenAttribute]

The ParseChildren Attribute is probably, the most important attribute you should pay attention to when developing web controls.  It's actually used by the ASP.NET Parser and ControlBuilder object to figure out how to parse the ASP.NET code you write.  Visual Studio also uses this attribute to figure out what valid sub-controls and components are allowed within the contents of a server control.

Let's say, I want to create an AggregateFeeds control that displays an aggregate list of RSS feeds.

A Basic and Boring Control Syntax

image

You'll notice that the RssResource is the only available option that is allowed as a child from the AggregateFeeds control.  Here's the code behind the AggregateFeeds control:

  113     [

  114     ParseChildren(

  115         typeof(RssResource),

  116         DefaultProperty = "Feeds",

  117         ChildrenAsProperties = true

  118         )

  119     ]

  120     public class AggregateFeeds : Control

  121     {

  122         public AggregateFeeds()

  123         {

  124             this.Feeds = new RssFeedCollection();

  125         }

  126         public RssFeedCollection Feeds

  127         {

  128             get;

  129             private set;

  130         }

  131         protected override void Render(HtmlTextWriter writer)

  132         {

  133             this.Feeds

  134                 .ForEach( rssRes => writer.Write( rssRes.Url ) );

  135         }

  136     }

  137 

  138     public class RssFeedCollection : List<RssResource>

  139     {

  140 

  141     }

  142 

  143     public class RssResource

  144     {

  145         public string Url { get; set; }

  146     }

The ParseChildren attribute on AggregateFeeds tells the ASP.NET, that any children within the AggregateFeeds control should be typeof(RssResource)ChildrenAsProperties=true let's ASP.NET know that it should STOP parsing server controls with "runat=server", and switch to instantiating objects into the properties of the ArggregateFeeds control.  DefaultProperty says, that the results of the parsed objects should go into the default property Feeds.

Syntax Goodness With InnerProperty

The previous example was great, it's simple and get's the job done.  But let's say, the requirements have changed, our control is growing, and we need to allow more customization, and extensibility for the consumers of our AggregateFeeds control.

Let's clean up the markup and allow our developers to create markup like this:

image

To get this type of syntactical behavior, check out the code below:

  113     [

  114     ParseChildren(

  115         ChildrenAsProperties = true

  116         )

  117     ]

  118     public class AggregateFeeds : Control

  119     {

  120         public AggregateFeeds()

  121         {

  122             this.Feeds = new RssFeedCollection();

  123         }

  124 

  125         [PersistenceMode(PersistenceMode.InnerProperty)]

  126         public RssFeedCollection Feeds

  127         {

  128             get;

  129             private set;

  130         }

  131         [PersistenceMode(PersistenceMode.InnerProperty)]

  132         public AggregateSettings Settings

  133         {

  134             get;

  135             private set;

  136         }

  137         protected override void Render(HtmlTextWriter writer)

  138         {

  139             this.Feeds

  140                 .ForEach( rssRes => writer.Write( rssRes.Url ) );

  141         }

  142 

  143     }

  144 

  145     public class AggregateSettings

  146     {

  147         public int TimeOut { get; set; }

  148         public bool CacheResults { get; set; }

  149     }

  150 

  151     public class RssFeedCollection : List<RssResource>

  152     {

  153 

  154     }

  155 

  156     public class RssResource

  157     {

  158         public string Url { get; set; }

  159     }

Notice, we've removed DefaultProperty and typeof(RssResource) from ParseChildren attribute.  We're no longer working with a simple control that has simple children objects that need to be parsed, we're now working with a complex control with more than one property that we're setting in the markup, so we've removed the "default" stuff.  The syntactical magic happens with PersitanceMode attribute on the properties.  PersistanceMode.InnerProperty allows us to specify our cool <Feeds> and <Settings> tags.  How does Visual Studio know what members are available?  It does so by Reflection.

Get fancy, more than one child type

Also, I want to point out, suppose, we want to support multiple types of Feed objects.  We could use an enum in RssResource, or we could use inheritance to achieve the following:

image

All we would have to do is simply mark RssResource as an abstract class. Then, subclass for each type.

  156     public abstract class RssResource

  157     {

  158         public string Url { get; set; }

  159     }

  160     public class MediaRss : RssResource

  161     {

  162 

  163     }

  164     public class ITunesRss : RssResource

  165     {

  166 

  167     }

Again, I'm just showing that it's possible, but following my mantra of "less code, less maintenance," I'd use an enum to describe the type of rss feed on RssResource.

Where is [PersistChildren]?

Nowhere!  Is PersistChildren attribute needed?  No, it's not a required attribute to create your custom control.  The PersistChildrenAttribute only provides designer support for your control with Visual Studio and has no "processing" affect in ASP.NET, but remember ParseChildren does.

I'm a image  source-view only guy.  I really don't remember the last time I've used the Visual Studio "Design View", it's a waste, crashes all the time, so I've pretty much given up on it.  Besides, "Design View" is for n00bs anyway.  Just kidding!  If you plan on using the Design View, then you'll probably need your PersistChildren attribute...

In general, PersistChildren and ParseChildren are exclusive complementary attributes to describe the same semantic operation.  The rule of thumb goes:

If ParseChildren(true), then PersistChildren(false)

If ParseChildren(false), then PersistChildren(true).

Following the PersistChildren guideline above should keep your code out of trouble.  But again, I wouldn't use PersistChildren only until you actually need it.  Less code, less maintenance.

Here's a nice list of attributes you should consider when writing your custom controls:

http://wdevs.blogspot.com/2007/10/attributes-to-consider-applying-when.html

Hope that helps! Happy coding!

Brian Chavez

NAnt Addin for Visual Studio (VS) 2008

image I've finally committed and upgraded VS 2008.  Fortunately, everything has gone pretty smooth.  Third party tooling support for VS 2008 is now reasonable, ReSharper, Code Rush, all now are supporting 2008.  But one of my favorite helper tools is NAntAddin developed by Netlogics Software.  It's quick and easy to execute specific NAnt tasks in the window.  Unfortunately, it doesn't support 2008 out of the box.

However, after playing around with the AddIn file, I was able to get NAntAddin working with VS 2008.

Here's how to do it:

  1. Download the latest version.
  2. Unzip and copy the addin files and folder to:

    On Vista:
    \Users\%UserName%\Visual Studio 2008\Addins

    On XP:
    \My Documents\Visual Studio 2008\Addins

    Note: If you don't see an "Addins" folder in, then create one under "Visual Studio 2008".
  3. Next, open the NAntAddin.Addin file with your favorite text editor, and edit the <version> value to 9.0 as shown below:

    image 

Now start Visual Studio 2008, and you should have NAntAddin up and running!

Your final directory structure should look like the following:

image

 

Happy coding!

Brian Chavez

10 Comments Filed Under [ Tips & Tricks ]
BadImageFormatException Errors

I've been playing with Lua Programming/Script Language and LuaInterface, because I have a need for embedding a scripting language in one of our projects.  Unfortunately, when trying to run one of the test case applications that came with LuaInterface, I was presented with a nice error shown below:

image

Anytime, you run a .NET application, the operating system reads the PE header information of the executable to help setup the process environment.  In my case, TestLua.exe was being setup and ran in x64 mode with an x64 runtime and failed to P/Invoke Lua's native 32-bit DLL.

Solution

In general, there are two main ways we can explicitly tell the operating system to load and use 32-bit process environments:

For applications and assemblies that you can not recompile:

  • Set the 32-Bit flag in the PE header. 

    For example, since the 32-bit flag in TestLua.exe was not set, I forced 32-bit mode by setting the 32-bit flag using CorFlags.exe:

    Start "Visual Studio SDK Command Prompt" and execute:
    CorFlags.exe /32bit+ TestLua.exe

For applications and assemblies that you can recompile:

  • Recompile using the "Target Platform" settings as illustrated here.

In practice, if you do low-level COM, P/Invoke, Win32 stuff, you'll probably need to set these 32-bit flags for your applications; however, if your application purely lives in the managed world, you won't need to do anything!

Add Comment Filed Under [ Tips & Tricks Errors ]
Vista Explorer Annoyances and Enhancements

image You might think this is a post about add-ons to Vista's Windows Explorer, but actually, it's a post about how to remove features in Vista's Explorer to make it actually usable and tolerable to work with.

Enhancement #1

Vista Explorer has the most annoying ability to "sniff folders" and try and guess what the file types are in your folder.  If .png, .jpg, or other image related file types exist in your folder, Explorer will switch to a "thumbnail/Large Icon" view, even though you've explicitly set a view to "apply to all" folders.  Here's how to get rid of the annoying behavior.

http://www.vistax64.com/tutorials/70819-windows-explorer-folder-view-settings.html

Enhancement #2

Vista Explorer forgets size & location.  Make Vista Explorer remember the size of the explorer window.

http://jtbworld.blogspot.com/2007/04/remember-vista-windows-explorer-window.html 

Enhancement #3

Segoe UI is the most annoying font in the world.  Change it here:

http://steve.fsxtreme.com/blogs/2008/01/16/say-no-to-segoe-and-cleartype-on-vista/

Seriously, the Windows Shell Team did a terrible job with Vista and they all need a few basic lessons on usability...

fighting0016.gif

Add Comment Filed Under [ Tips & Tricks Errors ]
The Bit Armory Visual Studio Theme

I recently upgraded to Vista 64-bit, and got hooked on the eye candy.  So, I decided to pimp out my IDE with my company's color theme. :)  Still working on some of the colors, but looks pretty good huh? Any suggestions?  I'm thinking I should tone down the save/modify color tracks near the line numbers so it fits in more....

image

How to fill open shapes in Visio

So, I was quite annoyed at Visio because I was lacking my Adobe Illustrator features, like filling in an open 2D shape.  Unfortunately, Visio doesn't have enough UI to allow you to set the fill of an open shape, but Visio is certainly capable of filling open shapes (contrary to what KB articles say).  Here's how to do it, let's first start by first drawing a simple square with the Pencil Tool:

image image

I filled the square with a red fill, and gave it a heavy dotted outline.  Now, open the ShapeSheet window:

image      image

Then manipulate the Geometry1 render table values by multiplying them by *1 and *0 and you'll get interesting results as shown below, here's what it looks like with my Gemometry1 table modifed:

  image  image

By the way, in case you're wondering, the LineTo points are just like a Cartesian coordinate XY graph.  Values are all relative to the origin which begins at the lower left of the object.  For example, Geometry1.X3, Geometry1.Y3, in the example above, are both Height*0 and Width*0, which is 0,0 origin. smile.gif  Have fun.  Hope that helps!

Visitor Pattern for User Interface and Display

I was browsing the NHibernate forums and came across a post by "thatmikewilliams" who posted the following code:

--------------------------------------------------------

Because this functionality is closely tied to the user interface you should probably use a visitor for this (rather than an overridden method in your class hierarchy).

package test.visitor;
public abstract class Payment {
   interface Visitor {
      Object visit(CardPayment payment);
      Object visit(CashPayment payment);
   }
   public abstract Object accept(Visitor visitor);
}

package test.visitor;
public class CardPayment extends Payment {
   @Override
   public Object accept(Visitor visitor) {
      return visitor.visit(this);
   }
}

package test.visitor;
public class CashPayment extends Payment {
   @Override
   public Object accept(Visitor visitor) {
      return visitor.visit(this);
   }
}

package test.visitor;
public class PaymentDisplayStringVisitor implements Payment.Visitor {
   public Object visit(CardPayment payment) {
      return "CC";
   }
   public Object visit(CashPayment payment) {
      return "CS";
   }
}

package test.visitor;
import java.util.ArrayList;
import java.util.List;
public class Test {

   public static void main(String[] args) {
      List<Payment> payments = new ArrayList<Payment>();
      payments.add(new CashPayment());
      payments.add(new CardPayment());
      
      PaymentDisplayStringVisitor visitor = new PaymentDisplayStringVisitor();
      for (Payment payment : payments) {
         System.out.println(payment.accept(visitor));
      }
   }
}

----------------------------------------------

Using the Visitor Pattern to display domain specific types on a user interface is a nice approach instead of overriding specific methods on your domain object, on top of that, cluttering your domain objects with useless "UI" specific methods like ("get object name").  Pretty interesting approach. :)  Notice the PaymentDisplayStringVisitor returns specific string type based on the type.  Very Cool.  I'll try extending this approach using .NET and Generics and post some code later.

NHibernate - null id in entry (don't flush the Session after an exception occurs)

imageI ran into this issue today when trying to persist one of my objects.  The cause of the problem was interesting.  I was trying to save an object when a property/columns in the table had a unique constraint.  As a result, the object that I was trying to persist would not persist simply because the object's property it failed to meet the unique constraint.

As a result, a call to Save() on the object failed and the ID on the object I was trying to save was not set, but NHibernate still processed the object and associated it with its persistence mechanism leaving it in a "semi-persistent" state with the NHibernate persistence manager (ie: NHibernate now knows about the object you tried to save and it SHOULD have fully evicted the object from its persistence manager because the save failed, but it didn't).

When an HTTP request finishes on my ASP.NET application, I flush and close all NHibernate session objects at the time the request is done.  And as a result, when the HTTP request finished, NHibernate attempted to flush the jacked up "semi-persistent" object (an object who's ID was null) and ultimately generating the error above.

So, the solution that I implemented was to wrap the Save() in a try{} catch{} statement, and if the save failed, immediately close and shutdown the session, handle the error/exception.  Then, check if Session.IsOpen when the HTTP request finishes.

Hope that helps, confused0081.gif

Brian Chavez

Remove Windows Service

You can remove windows services by executing the following command:

C:\> sc delete [service name]

TIP:  If you don't know the service name you're trying to delete, you can find it by going to Start>Run>services.msc and locate the service name in the service's property page.

image

2 Comments Filed Under [ Tips & Tricks ]
WMI Provider Error - Access Denied - TDSSNIClient initialization failed with error 0x5

imageI got an interesting error while trying to change the log on service account for SQL server.  I got a "WMI Provider Error" and a bunch of errors in the Windows Event Log.

Simple solution:

Restart.

The problem is simply, a Named Pipe issue.  Restarting re-creates the Named Pipe under the correct log on account.

 

 

 

 

If the restart fails, and you're still having problems connecting to SQL Server Remotely, try the following:

  • Set the log on account permissions on:

    C:\Program Files\Microsoft SQL Server
    C:\DATA DIRECTORY

    for the log on account.  You'll need to set "Full Control" permissions and make sure that you re-apply the rule to all children by clicking on the directory properties>Security>Advanced>Permissions>"Replace permission entries on all child objects..."

Hope that helps.

PNG Transparency and Cross Browser Compatibility

image If you are dealing with web-development, PNGs, and transparencies, this neat little trick should help.  Cross browser compatibility and support for PNGs isn't that good between IE5, IE6, IE7 and other browsers.  But there are some tricks you can do to help minimize PNG transparency problems while maximizing cross browsers compatibility.  The best technique that I've found for working with PNG transparencies is to use Adobe Fireworks to create PNG-8 images with "Alpha Transparency" indexes.  This eliminates the need for JavaScript/Filter Hacks to make PNG transparencies work correctly.  Here's the SitePoint article on how to do just that.

 


NOTE: I copied the following from the SitePoint article.  For some reason, Sunday 2:00AM 3/22/09 their servers were down and couldn't access the article.  So I pulled a cached version and appended it to this blog post to avoid loosing this gem article forever.  If the site point link article works, please use it instead (I'm sure they want their Ad revenue.)


By Alex Walker

I ran through this little Fireworks PNG trick in the Design View this morning and thought it was worth dropping in a blog post too. This is a method that’s been around for years, but I’m constantly surprised by how many people don’t know about it. Even in this office, I’ve had web gurus furrowing their brows and insisting “No, no … that can’t be right … can it?

So, at the risk of having long-time Fireworks users yawn, roll their eyes and think duh!, here it is.

As you probably already know, PNG comes in two flavors — 8-bit and 32-bit. It’s the 32-bit version that gets most of the fanfare.

PNG32’s major characteristics are:

  • It uses a flexible “JPEG-like” RGB color model, rather than a limited palette as GIF does.
  • It employs a completely lossless compression method, allowing you to save and resave your image with no loss of quality.
  • Lossless compression does come at some cost — PNG images are always much fatter than their JPEG equivalents.
  • It can reproduce complex, graded transparency settings, similar to a PSD or TIF file.

Of course, Microsoft’s scant regard for the PNG spec (authored way back in 1996) meant that the announcement of the glorious PNG format fell on deaf ears. And rightly so — as Internet Explorer was steadily grinding it’s way to a 95% share of the browser market, naturally an image format that rendered transparency as a solid, dishwater grey for most users qualified as a total non-event for the majority of developers.

Not to be bowed, a lot of bloodyminded developers set about inventing all manner of hacks, tricks and workarounds designed to force IE to play nice. These included many JavaScript/IE Filter-based solutions and even a Flash powered PNG renderer.

While most of these methods worked, all of them were complex, completely tied to the presence of another technology (Flash, JavaScript, etc.), and still failed badly on older browsers.

These efforts were, however, good attempts at making the best of a bad situation.

PNG8’s major characteristics are:

  • It employs a palette-based color model (sometimes called an indexed palette), like the one that GIF uses.
  • It can’t animate like GIF.
  • It offers GIF-like 1-bit transparency. Pixels are either solid or completely transparent, but never partially see-through.

Although this last point is generally accepted as fact, it isn’t strictly true, and this is the topic we’ll be examining today.

Transparency information for all PNGs is contained in a section of the file called a chunk, and according to the spec, for indexed images, it stores alpha channel values for one or more palette entries.

In other words, the chunk is allowed to have more than one transparency color.

Now, as we know, official specs can lay out all sorts of wonderful ideals involving rainbows and unicorns and fluffy kittens — just look at the most of W3C specs — but it’s what happens in the big, wide, dirty world that truly matters.

Let’s look at an example.

image

We’ll begin in Fireworks with a simple illustration that I’ve given a yellow translucent glow. As you can see in the screenshot below, the background is visible through the glow.

If we set our file format to PNG8 - indexed transparency, we get a result very much like any transparent GIF you might see. One color chip in our palette is set aside for the alpha channel, and all semi-transparent colors are flattened into the background color and rendered opaque.

image

However, if we switch from index to alpha transparency, things get interesting.

image

While our default alpha chip is still there in the top left corner, our PNG8 palette preview now shows a new type of color chip with a transparent chiplet cut out of the top-left corner. These are our semi-transparent colors.

Let’s export the graphic and see what our web browsers make of it. If you want to try your own quick tests, the page is here.

image

As you can see in the diagram above, all four modern browsers render the yellow glow effect beautifully, with subtly varying levels of transparency. No issues there.

But what about those cranky older IEs? Are they going to suck the life out of the party again?

The answer is: not necessarily.

image

Granted, older browsers won’t render the gentle glow effect, they’ll happily ignore it while continuing to render the 100% transparent parts in glorious, GIF-like, 1-bit alpha. Not perfect, but not tragic either — particularly when compared to the ugly grey boxes that accompany unhacked PNG32s on older versions of IE. Keep in mind that all the IE filter based PNG hacks still leave a grey box in IE5.

Amazingly, Fireworks seems to be the only graphics app that supports this semi-transparent PNG8 export feature — and it has done so since at least version 3.

I can certainly confirm that none of PhotoShop, Gimp, Paintshop Pro, or Xara has this functionality built-in. Since I first published this in the DV, forum member Danieljames has reported that two small apps — pngquant and pngnq — can mimic this trick. However it appears that Fireworks does a better job, so obviously if you have even an older version of Fireworks hanging around, it’s probably worth holding onto just for this feature!

Summary

It seems there are very few reasons for not using more 8-bit Fireworks PNGs in our work. In many typical situations, between 60% and 80% of users will be using a browser that fully supports these files.

image

The remaining IE5-6 users will see a slightly jaggier but often very acceptable version of the same image. The example to the right is used on the sitepoint.com home page, and I doubt IE6 users are aware that they’re missing anything.

The generated files are small — the light globe image used in the examples above was less than 6k. I generated a PNG32 version of the same image and it was 3 times the size.

And as they have no reliance on browser hacks, JavaScript, Flash, DirectX, or any other third-party technology, it’s difficult for them to fail.

While there still may be times when full transparency control in all browsers will demand the PNG32 hacks, personally I think PNG8 should become the default choice for web transparency effects.

AJAX and ASP.NET Template Controls

I was programming today (err. early morning, 1:00 AM) and stumbled across this error:

[NullReferenceException: Object reference not set to an instance of an object.]

   AjaxControlToolkit.ExtenderControlBase.LoadClientStateValues() in d:\E\AjaxTk-AjaxControlToolkit\Release\AjaxControlToolkit\ExtenderBase\ExtenderControlBase.cs:332

   AjaxControlToolkit.ExtenderControlBase.Page_PreLoad(Object sender, EventArgs e) in d:\E\AjaxTk-AjaxControlToolkit\Release\AjaxControlToolkit\ExtenderBase\ExtenderControlBase.cs:287

   System.EventHandler.Invoke(Object sender, EventArgs e) +0

   System.Web.UI.Page.OnPreLoad(EventArgs e) +86

   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +948

AJAX apparently blew chunks.  After taking a look at the AJAX source code ExtenderControlBase.cs (thank goodness it's open source), the LoadClientStateValues() was trying to load some hidden client state data stored in a hidden control being resolved by FindControl() method on NamingContainer.  Well, because I was using my AJAX control in a LayoutTemplate, NamingContainer tuned out to be null which was causing ASP.NET's OnPagePreload -> LoadClientStateValues() to fail.

Here was the offending code:

<asp:Login ID="Login2" runat="server" OnLoginError="Login2_LoginError">

    <LayoutTemplate>

            <fieldset>

                <div class="panel-username">

                    <p>

                        <asp:Label ID="UserNameLabel" runat="server" AssociatedControlID="UserName" CssClass="labeltext bold">Email Address:</asp:Label>

                        <asp:TextBox ID="UserName" runat="server" CssClass="textbox"></asp:TextBox>

                        <ajax:TextBoxWatermarkExtender ID="TextBoxWatermarkExtender1" runat="server" TargetControlID="UserName"

                            WatermarkText="Enter Email Address" WatermarkCssClass="watermark">

                        </ajax:TextBoxWatermarkExtender>

                        <asp:RequiredFieldValidator ID="UserNameRequired" runat="server" ControlToValidate="UserName"

                            ErrorMessage="User Name is required." ToolTip="User Name is required." ValidationGroup="ctl00$Login2">*</asp:RequiredFieldValidator>

                    </p>

                </div>

                <div class="panel-password">

                    <p>

                        <asp:Label ID="PasswordLabel" runat="server" AssociatedControlID="Password" CssClass="labeltext bold">Password:</asp:Label>

                        <asp:TextBox ID="Password" runat="server" TextMode="Password" CssClass="textbox"></asp:TextBox>

                        <asp:RequiredFieldValidator ID="PasswordRequired" runat="server" ControlToValidate="Password"

                            ErrorMessage="Password is required." ToolTip="Password is required." ValidationGroup="ctl00$Login2">*</asp:RequiredFieldValidator>

                    </p>

                </div>

                <div style="float: left; width: 150px;">

                    <p>

                        <span class="bold">Don't have an account?</span> <a id="A1" href="~/common/SignUp.aspx"

                            runat="server">Register here</a>. It's easy and free!</p>

                </div>

                <div class="panel-button">

                    <p>

                        <asp:ImageButton ID="LoginButton" runat="server" CommandName="Login" ValidationGroup="ctl00$Login2"

                            ImageUrl="~/Images/TransparentPixel.gif" CssClass="cmdSignIn" />

                    </p>

                    <p style="padding-top: 10px;">

                        <a href="#">Forgot password?</a></p>

                </div>

            </fieldset>

    </LayoutTemplate>

</asp:Login>

As you can see, the offending line of code is marked in bold above.  I was using the TextBoxWatermarkExtender on the UserName TextBox control.  Since AJAX needs a NamingContainer, a simple work around is to simply wrap the code in a ASP.NET Panel control, and you're problems will go away like so:

<asp:Login ID="Login2" runat="server" OnLoginError="Login2_LoginError">

                    <LayoutTemplate>

                        <asp:Panel ID="panWrapper" runat="server">

                            <fieldset>

                                <div class="panel-username">

                                    <p>

                                        <asp:Label ID="UserNameLabel" runat="server" AssociatedControlID="UserName" CssClass="labeltext bold">Email Address:</asp:Label>

                                        <asp:TextBox ID="UserName" runat="server" CssClass="textbox"></asp:TextBox>

                                        <ajax:TextBoxWatermarkExtender ID="TextBoxWatermarkExtender1" runat="server" TargetControlID="UserName"

                                            WatermarkText="Enter Email Address" WatermarkCssClass="watermark">

                                        </ajax:TextBoxWatermarkExtender>

                                        <asp:RequiredFieldValidator ID="UserNameRequired" runat="server" ControlToValidate="UserName"

                                            ErrorMessage="User Name is required." ToolTip="User Name is required." ValidationGroup="ctl00$Login2">*</asp:RequiredFieldValidator>

                                    </p>

                                </div>

                                <div class="panel-password">

                                    <p>

                                        <asp:Label ID="PasswordLabel" runat="server" AssociatedControlID="Password" CssClass="labeltext bold">Password:</asp:Label>

                                        <asp:TextBox ID="Password" runat="server" TextMode="Password" CssClass="textbox"></asp:TextBox>

                                        <asp:RequiredFieldValidator ID="PasswordRequired" runat="server" ControlToValidate="Password"

                                            ErrorMessage="Password is required." ToolTip="Password is required." ValidationGroup="ctl00$Login2">*</asp:RequiredFieldValidator>

                                    </p>

                                </div>

                                <div style="float: left; width: 150px;">

                                    <p>

                                        <span class="bold">Don't have an account?</span> <a id="A1" href="~/common/SignUp.aspx"

                                            runat="server">Register here</a>. It's easy and free!</p>

                                </div>

                                <div class="panel-button">

                                    <p>

                                        <asp:ImageButton ID="LoginButton" runat="server" CommandName="Login" ValidationGroup="ctl00$Login2"

                                            ImageUrl="~/Images/TransparentPixel.gif" CssClass="cmdSignIn" />

                                    </p>

                                    <p style="padding-top: 10px;">

                                        <a href="#">Forgot password?</a></p>

                                </div>

                            </fieldset>

                        </asp:Panel>

                    </LayoutTemplate>

                </asp:Login>

Now it works :)  Hope that helped anyone running into the same problem.  Whenever you're dealing with ASP.NET template controls, and you're using AJAX within these template controls, be sure to wrap the control pointed to by TargetControlId & the AJAX control itself in it's own naming container to avoid issues like this.  Another bug down fighting0028.gif. :)

2 Comments Filed Under [ Tips & Tricks Errors ]
How to create tile-perfect diagonal lines in Illustrator

Creating diagonal lines in Adobe Illustrator is somewhat of a pain.  I'm creating the graphics for our new Web 2.0 site, and had a hard time creating diagonal lines.  But here I'll show you how to create angled 45deg Web 2.0 lines in Illustrator with relative ease.

 

First, turn snap to grid on.

 image

Select the line tool, set the stroke width to 5pt (or your desired width).

image

Make sure your stroke color is the color you want it.  In this example, my stroke color is black.  Next, on the canvas, draw a diagonal line that is slightly larger than the major grid box.

image

image

Next, Move-Copy the line 12px away from the first line.

image

image

Hit the copy button.  Once your copy appears on the canvas, press CTRL-D to repeat.  You need to repeat until you have a major grid completely covered.  Like so:

image

Next, select all the diagonals then go to Object>Path>Outline Stroke as shown below:

image

image

image

Next, draw a square (with no fill and no stroke) as the same size of a major grid box (72px by 72px) and place it over the covered major grid like this:

image

Your square should be 72px width and height.  Next, select all, and click Divide on your Path Finder as shown below:

image

image

image

Ungroup and cut the excess diagonals from the major square:

image

image

image

Now you should have a nice cut pattern like the one above.  Select your pattern and drag it to your swatches.  Once you see your pattern in your swatches palette you can then use the swatch and apply a fill to your irregular pattern and archive the following results:

image

Pretty cool! :)  Hope that helps! happy0122.gif

Helpful Tip:

If you want to apply a radial gradient or a fill color to your stripes, you'll notice that this method wont work.  But to make it work, you just need to continue a little more.  Select the original pattern you created:

image

Next, Merge:

image

(This effectively merges the original invisible (no stroke no fill) square with your diagonals.)

If you choose to stop here, you'll notice the pattern diagonals still act like individual objects when a fill is applied, and you get something like a diamond shape when applying a radial gradient:

image

To unify the stripes as a single object do the following (and ultimately, have the gradient applied to the diagonals as a whole, instead of individually), Ungroup:

image

Then Add Shape Area in your path finder tools:

image

Then click Expand:

image

Now you have the gradient applied to the whole shape instead of each individual diagonal line:

image

There we go!  Hope that helps!

Slink Framework - Strongly Typed URLs for ASP.NET

 image926

image_thumb15_thumb45

I decided it was time to solve a very annoying and time consuming code maintenance/quality problem when working with ASP.NET and Visual Studio, URL verification.  If you're like me, you've probably had your fair share of HTTP 404s and ASP.NET maintenance troubles whenever you renamed a file in your web project and broken URLs in the code-behind pages that contain scattered uses of Response.Redirect() similar to the following:

protected void Page_Load(object sender, EventArgs e)

{

    if ( User.IsInRole( "admin" ) )

    {

        Response.Redirect( "~/Page2.aspx" );

    }

    if( User.IsInRole( "employee" ) )

    {

        Response.Redirect( "~/EmployeePages/ViewCustomers.aspx" );

    }

    if( User.IsInRole("customer") )

    {

        Response.Redirect( "~/CustomerPages/ViewCatalog.aspx" );

    }

}

The site validation in Visual Studio somewhat is limited in its ability to validate URLs.  Visual Studio validates URLs in the HTML markup view, but doesn't validate your URLs in code-behind pages.  That's a bummer, because the code above is somewhat common in projects.  Invalid URLs that exist in your code-behind pages are hard to debug and locate... you usually don't know when you have an invalid URL lurking in your code-behind until you hit the page with your browser.  Most modern refractoring tools today do a good job refactoring code for renamed files; however, since most refactoring tools are searching for strings when renaming an ASPX file, there is a potential for error.  There have been many times when refactoring didn't help me and only made the problem worse by selecting the "search string literals" option.  Refactorability degrades when you start dealing with different media types in your markup and code-behind pages, such as Images, SWF, CSS, and JavaScript URLs.  Media types like these go unchecked, try refactoring those in your pages!mad0259.gif  Personally, I'd love it if there was some kind of strongly typed URL framework.  Fortunately, there has been some work in this area by Fabrice Marguerie and his open source project PageMethods.  In summary, PageMethods was too strict, and didn't work well for my purposes.  I simply wanted a light-weight and fast URL framework to provide links to pages and media objects that I could use in code-behind pages and HTML markup.  I also wanted to know at compile time the validity of all the URLs in my project.  So, I decided to tackle the problem myself with a small project I created called (Strong Link), aka Slink.

Now, let's revisit the same maintainability problem above using Slink with strongly typed URLs:

protected void Page_Load( object sender, EventArgs e )

{

    if( User.IsInRole( "admin" ) )

    {

        Response.Redirect( Slinks.Page2.TidleUrl );

    }

    if( User.IsInRole( "employee" ) )

    {

        Response.Redirect( Slinks.EmployeePages.ViewCustomers.TildeUrl );

    }

    if( User.IsInRole( "customer" ) )

    {

        Response.Redirect( Slinks.CustomerPages.ViewCatalog.TildeUrl );

    }       

}

With Slink, not only do you get cleaner code, you get compile time checking for code-behind pages! You can also use type safe links in HTML markup:

<h4>Customer Pages</h4>

 

<!-- The old way, using relative path -->

<img src="~/Images/CustomerImage.jpg" alt="not strongly typed image" />

 

 

<!-- The new Slink type safe way, using img HTML tag -->

<img src='<%# Slinks.Images.JPG.CustomerImage.TildeUrl %>' alt="strongly typed url"

     runat="server" />

 

<!-- The new Slink type safe way, using a web control -->

<asp:Image ID="imgControl" runat="server"

           ImageUrl='<%# Slinks.Images.JPG.CustomerImage.TildeUrl %>' />

Yeah! And the list goes on:

  • Better Maintainable Code
  • Better Cleaner Code
  • Better Readable Code
  • Better Refactorable Code
  • Better Quality Code
  • Support for media types other than ASPX pages
  • Fast code generation
  • Non-intrusive overhead (no need to call any setup methods or expensive runtime checking)
  • Use as-you-go integration (doesn't require any rewrites of your code to start using Slink)
  • XML configuration based
  • Intellisense for any of your files and media objects!

Now that's what I'm talking about. So how do you get your hands on all this Slink ASP.NET goodness?  Keep reading...

 

Getting Started with Slink

There are two basic ways to use Slink:

  • You can use Visual Studio and an accompanying CR_Slink Plug-In (via DXCore) to automatically generate a type safe file in your projects App_Code directory.

OR

  • You can use Slink.exe in a build task to generate a strongly typed safe file in your App_Code directory.

Details about how to setup each method is discussed later.  First, there's some XML configuration you'll need to perform to tell Slink what to generate.  Here is a sample configuration that you place in your Web.config:

<!-- Web.config -->

<configuration>

  <configSections>

       <section name="Slink" type="Slink.Core.SlinkConfigSection, Slink.Core"/>

  </configSections>

  <Slink>

     <GlobalSettings EngineEnabled="True" RootNamespace="Slinks"/>

     <NamespaceRules>

        <add key="aspxFiles" Extension="*.aspx" UseFolderNamespace="True"/>

        <add key="jpgFiles" Extension="*.jpg" NamespaceOverride="Images.JPG"/>

        <add key="pngFiles" Extension="*.png" NamespaceOverride="Images.PNG"/>

     </NamespaceRules>

  </Slink>

  <!-- Other configuration settings go here -->

</configuration>

Below is a brief explanation of the XML configuration settings...

<section name="Slink" type="Slink.Core.SlinkConfigSection, Slink.Core"/>

  • This section handler needs to be added to the <configSections>.  The <section> tag defines the XML node that is to be handled by the SlinkConfigSection on behalf of the .NET configuration framework.

<Slink>

          <GlobalSettings EngineEnabled="True" RootNamespace="Slinks"/>

  • The <GlobalSettings> node has two attributes EngineEnabled and RootNamespace.
    • EngineEnabled - Boolean - This is a project level setting. You may want to disable type safe link code generation at the project level if you are working with multiple Web Projects.  Setting EngineEnabled="False" disables code-generation at the web-project level.
    • RootNamespace - String - Allows you to specify the Namespace for all type safe links.

image_thumb115 

<NamespaceRules>

    <add key="aspxFiles" Extension="*.aspx" UseFolderNamespace="True"/>

    <add key="jpgFiles" Extension="*.jpg" NamespaceOverride="Images.JPG"/>

    <add key="pngFiles" Extension="*.png" NamespaceOverride="Images.PNG"/>

</NamespaceRules>

  • <NamespaceRules> are at the core of Slink.  Namespace rules dictate how type safe code is generated by the Slink Engine.  Namespace rules allow you to define what type of files get type safety.
    • Extension - String - If you wish to have type safe code generated for all ASPX pages, add a namespace rule with the Extension attribute set to "*.aspx". Including the * (asterisk) is necessary.
    • UseFolderNamespace - Boolean - Uses the file path to generate the sub-namespaces below the root namespace.
    • NamespaceOverride - String - Overrides the UseFolderNamespace attribute and allows you to define your own custom path.  Your custom namespace override is appended to RootNamespace. See the example below for JPG and PNG namespace overrides:

image_thumb15_thumb35

NOTE: If you have multiple files with the same name but different extension, you'll want to override namespaces to avoid type collision.

Now that we have XML configuraiton out of the way, I'll walk you through on how to install Slink on your machine.

 

Using Visual Studio Slink Plug-In

image_thumb285

Installing VS.NET Plug-In

  1. Install the DXCore (free) extensibility framework for Visual Studio from Developer Express here.
  2. Download the Slink binaries Slink_bin.zip.
  3. Copy the contents of Slink_bin.zip into your DXCore Plug-In directory
    • Ex: C:\Program Files\Developer Express Inc\DXCore for Visual Studio .NET\2.0\Bin\Plugins
    • Note: All contents of the Slink_bin.zip must be extracted into the plugins directory.
  4. Make sure your XML config section is defined in your Web.config, and start coding away!

 

Using Slink.exe

image_thumb275

Now, if you're already using the Visual Studio Plug-In, there's no need to use the Slink.exe.   But for those of you who don't have Visual Studio, or are using Visual Studio Express, using Slink.exe is the way to go.

Installing Slink.exe

  1. Download the Slink binaries Slink_bin.zip.
  2. Extract the contents of to the directory of your choice
    • Ex: C:\Tools
  3. Run the following from the command line:
    • C:\Tools> slink.exe /webproject:<PathToWebProject>
    • Replace <PathToWebProject> with the full path to your project.
  4. Be sure to modify your Web.config and your Namespace Rules are set.  Otherwise, the Slink won't know what to do.

TIP: Unfortunately, Web Projects in Visual Studio are handled differently than ordinary projects.  With web projects, you can't specify any "Pre-Build" event tasks.  But there's an easy workaround for this limitation.  If you're using Visual Studio Express, and want to have your types generated before the build process/verification of your main web project, you can create a standard dummy "Class Library".  In the pre-build event for your dummy "Class Library" you can setup Slink to execute.  Then, add the dummy "Class Library" to your main web-project.  Now, anytime you build your website, your class library will be built first (and slink will run) before the build / verification process takes place on your main web-project.

That all!  After building web project (if you're using the VS.NET Slink Plug-In) or when you execute Slink.exe, you should get a file named <WebProject>\App_Code\Slinks.cs that contains your type safe URL generated code.

If you have any questions, comments, or suggestions please feel free to contact me. I hope other developers find the Slink framework useful.  Happy coding!


Slink CodePlex Project

http://codeplex.com/slink

 

Thoughts & future improvements to Slink

  • Add support for strongly typed parameter passing/parsing for query string parameters.
  • Create a standalone Slink Plug-In that does not rely on DXCore.
  • Implement more advanced code generation caching.
  • Possibly implement /code generate a helper methods on media types such as "MyImage.GetStream()" that would automatically open and return an IO stream.

 

Licence

This library and code generator is licensed under the terms and conditions defined in the GNU Public License. You are free to use it for non-commercial purposes. If you are going to use any part of it in a commercial application, contact me and we can work something out.  You may use the code generated output of Slink in both commercial and non-commercial applications.

Special Thanks

Special thanks and acknowledgements go out to Philip Laureano for building his open source TaHoGen code template generator.  Without it, Slinks would not exist.

General Database Design Guidelines and Naming Conventions

Here are some helpful tips on database naming conventions. Consistency, readability, maintainability, and extensibility are some of the most important factors when designing new databases. In this blog I'll go over some conventions I use to keep myself consistent. If you have any conventions you follow or ways to improve these conventions, let me know. :)

Entity Class Naming

The name of our entity classes should be in the singular form, for example Account, Customer, or User (for a user accounts table). Plural names (such as Accounts, Orders, and Order Details) aren't good candidate for entity names because 1) plural names don't grammatically fit well when reading relationships that are self-referencing and one-to-one 2) it reduces the readability of SQL statements when fully qualified names the WHERE clause. To Illustrate:

/* Using singular form */

SELECT * FROM Account WHERE Account.ID = 1;

 /* Using plural form */

SELECT * FROM Accounts WHERE Accounts.ID = 1;

       

If you ask me, the singular form reads much better in the WHERE clause, but the plural form performs better in the FROM clause. When creating complex SQL queries, readability in the WHERE clause tends to outweigh the benefits of readability in the FROM clause. This is why singular table names are generally better. Furthermore, the name of the entity should be representative of a single row in the table. Names like History, Schedule, and Table are not descriptive enough.

For certain types of entities, special keywords should be contained in the naming of the entity. Below is a list of special entities and associated key words that should be considered a part of the naming scheme.

  • Tracking History: History, Historical, Event

         

Attribute Naming

Below is a small list of naming guidelines for naming columns based on the type of data they hold.

  • Identifiers: Number (or No), Code, Identifier (or Id), Tie-Breaker
  • Categories: Type, Method, Status, Reason
  • Counts: Count
  • Dimensions: Length, Width, Height, Weight
  • Amounts: Amount, Price, Balance
  • Factors: Rate, Concentration, Ratio, Percentage
  • Specific Time Points: Timestamp, DateTime, Date, Month, Year
  • Recurrent Time Points: TimeOfDay, DayOfWeek, DayOfMonth, DayOfYear, MonthOfYear
  • Intervals: Duration, Period
  • Positions: Point, LineSegment, Polygon
  • Texts: Name, Description, Comment, Instructions

Try to avoid abbreviations; it may likely confuse business people using the database.

Natural Keys vs Surrogate Keys

When choosing the primary key for a table, often in designs, natural keys occur in the business problem. For example, if we're modeling a Person table in our database we might be inclined to use the Social Security number (a natural key) of a person as the primary key in the Person table. This isn't a bad design, since everyone in the US should have a Social Security number; however, keying the Person table with a Social Security number as the primary key doesn't lead to an extensible design. What happens if the system and database we're designing for needs to handle people who are not US citizens or people who don't have a Social Security number? As you can see, using a Surrogate Key named PersonId with an identity constraint as our primary key is a much better extensible database table design than using a natural key. In most cases, even if the natural key is truly unique, I would still use a Surrogate Key.

 

That's all for now! If I come think of some more, I'll add them to this blog post later. :) Keep in mind there is no "best practice" because any best practice can be turned into a worst practice if the situation changes. The point is the schema design of every database should be well thought out. Being consistent in your designs help leads designs to be readable and maintainable. Extensibility leads your designs to be changed and refactored when business processes change.