Friday, April 3, 2009

Enabling syntax highlighting in your Blogger Blog

This is a test of the SyntaxHighlighter code snippet formatter.

public void Foo(string bar, int baz)
{
if (YouSeeThis())
{
Console.WriteLine("It worked!");
}
}
For the above to work you need to have the following code:

<script src='http://[yourhostname]/scripts/shCore.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushGroovy.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushScala.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushVb.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushXml.js' type='text/javascript'/>
<link href='http://[yourhostname]/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://[yourhostname]/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script class='javascript'>
//<![CDATA[
function FindTagsByName(container, name, Tag){
var elements = document.getElementsByTagName(Tag);
for (var i = 0; i < elements.length; i++){
if (elements[i].getAttribute("name") == name){
container.push(elements[i]);
}
}
}
var elements = [];
FindTagsByName(elements, 'code', 'pre');
FindTagsByName(elements, 'code', 'textarea');

for(var i=0; i < elements.length; i++) {
if(elements[i].nodeName.toUpperCase() == 'TEXTAREA') {
var childNode = elements[i].childNodes[0];
var newNode = document.createTextNode(childNode.nodeValue
.replace(/<br\s*\/?>/gi,'\n'));
elements[i].replaceChild(newNode, childNode);
}
else if(elements[i].nodeName.toUpperCase() == 'PRE') {
brs = elements[i].getElementsByTagName('br');
for(var j = 0, brLength = brs.length; j < brLength; j++) {
var newNode = document.createTextNode("\n");
elements[i].replaceChild(newNode, brs[0]);
}
}
}
SyntaxHighlighter.all();
//]]>
</script>

Thanks go to the following for getting this working:

Tips for software engineer: Using SyntaxHighlighter on BLOGGER

Test of SyntaxHighlighter

This is a test of the SyntaxHighlighter code snippet formatter.

public void Foo(string bar, int baz)
{
if (YouSeeThis())
{
Console.WriteLine("It worked!");
}
}
For the above to work you need to have the following code:

<script src='http://[yourhostname]/scripts/shCore.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushGroovy.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushScala.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushVb.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushXml.js' type='text/javascript'/>
<link href='http://[yourhostname]/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://[yourhostname]/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script class='javascript'>
//<![CDATA[
function FindTagsByName(container, name, Tag){
var elements = document.getElementsByTagName(Tag);
for (var i = 0; i < elements.length; i++){
if (elements[i].getAttribute("name") == name){
container.push(elements[i]);
}
}
}
var elements = [];
FindTagsByName(elements, 'code', 'pre');
FindTagsByName(elements, 'code', 'textarea');

for(var i=0; i < elements.length; i++) {
if(elements[i].nodeName.toUpperCase() == 'TEXTAREA') {
var childNode = elements[i].childNodes[0];
var newNode = document.createTextNode(childNode.nodeValue
.replace(/<br\s*\/?>/gi,'\n'));
elements[i].replaceChild(newNode, childNode);
}
else if(elements[i].nodeName.toUpperCase() == 'PRE') {
brs = elements[i].getElementsByTagName('br');
for(var j = 0, brLength = brs.length; j < brLength; j++) {
var newNode = document.createTextNode("\n");
elements[i].replaceChild(newNode, brs[0]);
}
}
}
SyntaxHighlighter.all();
//]]>
</script>


Thanks go to the following for getting this working:

http://developertips.blogspot.com/2007/08/syntaxhighlighter-on-blogger.html

Thursday, April 2, 2009

NAnt/MSBuild ClickOnce publishing ‘publish.htm’

The secret to this is specifying in the properties passed to MSBuild either directly or via NAnt. There are two specific properties you need to get the publish.htm published:

CreateWebPageOnPublish true
WebPage publish.htm

You can specify these as command line parameters as follows:

/property:CreateWebPageOnPublish=true

/property:WebPage=publish.htm

Once you are passing these parameters to MSBUILD it will move your publish.htm up to your publish location. Note, that there are many more properties that you can specify in the same way. Take a look inside of your .csproj file Property/PropertyGroup for a list of the values. You can experiment with the GUI inside of Visual Studio and then see how the values change so you can tweak your MSBuild/NAnt script accordingly.

UPDATE: It turns out I'm wrong on this. The above solution does not auto-generate a publish.htm. More to follow.


Technorati Tags: ,,

Adding your own Pre-requisite installer to a ClickOnce app

STEPS

  • Download and install the Bootstrap Manifest Generator
  • Start a New Project and choose Package Manifest
  • Give your project a name and code (these can be the same)
  • Click on Project/Add Install File and choose your installer
  • Give a Display Name in the Install File settings
  • Build your project with Project/Build
  • On Vista this will ignore any properties about where it creates the file. Look for it in \Users\{username}\Documents\{Project Name}
  • Copy this to your packages location. Usually here: C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\

You should now be able to choose this in your Project Properties\Publish\Prerequisites list.

LINKS

Bootstrap Manifest Generator

Customising your ClickOnce deployment

Technorati Tags: ,,

Monday, March 16, 2009

Is your application ready for deployment?

So, you’ve coded like a banshee for 7 weeks straight, listened to your manager badger you about “sprint” this, “agile” that, “can you tell me when its really going to be ready to install at the customer’s site?

Well, before you go there, you should run through a pre-deployment checklist. Here’s one that I’ve come up with after going through the motions on a number of occasions.

Build and CI

If you’re not using NAnt or MSBUILD scripts then start right now! The first thing you should do when you’re building out your new project source tree is to get it committed to your version control system and then make sure it will be built by your Continuous Integration server.

By integrating constantly you’ll know when the changes you are making are going to break what someone else is working on. I hear talking about changes they’ve held on to for weeks before attempting to commit them to version control out of fear of breaking the build. Face it, the days of Big Bang check-ins and waiting for the nightly build are light years behind us now.  To move fast, we have to identify the risks before it hits the deadline.

DO YOU KNOW YOUR INSTALLER?

How many times have you been burned by this:

Larry - You know, file fizzbin.dll is missing from the build.

Joe – Did you add it to the installer?

Larry – We have an installer?

Alright, I played that up a bit, but you catch my drift. Installers can be quite complicated beasties. In my team, I adopted a stripped down open source installer (Inno Setup). Sure, it doesn’t have all of the bells and whistles of some of the big name installers, but its damn simple. I combined that with something that we use every day (NAnt) and now we’ve got a half-way decent installer pattern.

If you write code, you should understand how your bits (DLLs, XML files, web files) get to where they need to go. Here are some things you should ask yourself about any file that needs to go into the installer:

  1. Is this a DLL? Is it already part of one of the projects whose output will be installed to the ‘bin’ directory, or is this something new?
  2. Is this a Configuration File? Should the values be preserved between installations/upgrades? How should I take care of values that are Added/Removed/Updated? Which services will access this file? Will the correct permissions be assigned to the file/directory? Does this file need to survive an uninstall?
  3. Is this a web virtual? Is there anything special that needs to be done to the virtual in the IIS Configuration? Does it need to be locked down?
  4. Is this a Windows Service? Have you followed the same naming conventions for the name, the .exe, the log file? The three of these should be similar in name so its easier for support to identify which service is associated with which executable and log file.
  5. Logging? Did you make sure that you are logging to the Log directory?
  6. Are there files that you no longer want to be included?

HARD CODED VALUES

OK, nobody does this anymore. We all have all the time we need to isolate the hard coded strings and have already moved them to configuration files or they reside inside of a resource file.

Now really, we all do this in our rush to quickly prototype the code we’ve got to get finished for the upcoming trade show or GA release of version 5.8. But really, you need to identify and move these values first to say a common access class and from there to a configuration file.

Check your configuration files

So all the code is done, you’ve made it through your xUnit tests and QA is saying that the risks are acceptable to deploy this app. And yet the application most likely has never been deployed to an environment similar to your (or your customer’s) production environment. So, now comes the hard part, we have to adjust all those configuration settings (URLs, passwords, connection strings, file paths, frequency values, etc). Sure that’s great. I know where all of those are. OK, but how many of those values are REPEATED in your configuration files? You know like, IP addresses to servers, account names, etc.

For those of us that enjoy using Resharper you become smoking ninja’s with your ability to keep your code DRY. But what about the ‘data’ in your configurations? How many connection strings do you reference? Do you have URL’s for services that contain the same server name over and over again?

If we apply the DRY principle to our configuration files as well as our code, then its far easier to create instructions on which values to change for production deployment, or better yet to automate or provide tools to safely adjust these values (and even better yet, make sure that the values that are in the configuration files will work when the service/application is running!)

Database connection string

Hey, you’ve tested this, you know it works. Works for me! Every time. Recently we had a “head scratching” moment with our newly arrived QA engineer. She’d built out a VM and installed our software on it to discover that one of our applications didn’t run at all after installation. My team looked at it and said, “Hmmm… that can’t be happening. It works everywhere else. Let’s rebuild your server and install again.” So, after rebuilding the server it worked fine and dandy.

Some weeks later, I stumbled upon a hard coded connection string in the previously mentioned application and had my “AH-HA” moment, “So this is why it failed!”. If you’ve been reading above then we should have reviewed this and identified that first, there was a hard coded string containing a connection string and second it was duplicated.

So, what’s the lesson here? Well, the deployment environment should be taken into account even when a developer is writing and testing his/her own code. In this particular case, we would have recognized that the connection string was pointed to localhost\sqlexpress and it needed to honor what has in our connections.config file.

mock me? NO MOCK YOU!

OK, funny! In today’s world we need to be able to provide “fake” interfaces or simulate external services. The only way to make sure that you’re really ready for the vagaries of what you’ll find out in the production wilderness is to mock the different services that you connect to. The benefits will allow you to have confidence that the application you’ve written will stand up when it encounters unexpected results.

This is really a follow on to TDD. Test driven development actually leads to building out mocked interfaces.

Naming Conventions

If you are writing an application for a company and there is more than one application you’ll want to follow similar patterns when naming and identifying your application. Things to keep in mind:

  • Keep track of the ports that you use if you use WCF services, proprietary listeners, etc. Support and the customer will want to know if your application needs to have inbound or outbound access on specific ports. Also, when it comes to TCP/IP ports, you really should check for a port range that is not used by other applications. Anymore, that is up in the 38,000+ range and anything below 10,000 should be reviewed carefully.
  • Name your virtuals so they are consistent, easy to type and make sense for their intended purpose.  Again you might have a common prefix for your application suite, or common suffixes for types of applications.
  • Windows services are a big pet peeve of mine. Make sure you’ve made sure that you have a consistent Service Name, Display Name and you’ve taken some time to write a decent 10-20 word description of what the service is.
  • Finally, make sure that your DLLs have the appropriate information in the ApplicationInfo files. The Company Name, Copyright, Product Name and version should all be there and be current. You can accomplish this by hand or by incorporating some steps into your build file.

Last Thoughts

This is entirely too long and I’ve most likely lost a lot of people by now. But the last step you should think through is about what you’ve done to your application during your own testing. Do you normally change values in the configuration files to debug settings? Have you deployed with the Log Level set to Debug? Have left the web.config with the debug turned on? Are you including your symbol files?

There’s a lot more of these types of questions that you should think about when you release your application into the wild. Some of this is about your ability to control your ADD (attention deficit disorder or bright shiny object chasing) and concentrate for an hour or two on the questions and topics I’ve brought up here.

Now Playing - Tom Scott - Reed My Lips - Saxappella

Thursday, March 12, 2009

xUnit tests and threads

OK, it goes against the idea of unit testing a little bit, but sometimes you can only get some code to fail by having another thread attempt to change a shared value. In my case, I hade a piece of code like this:

var thread = new Thread(() => Assert.NotNull(null));
thread.Start();
thread.Join();



This block of code starts a thread and checks that the value, null, is not null. The xUnit Assert will throw an exception once the thread is running. What happens to uncaught exceptions in threads? In the old 1.0 and 1.1 days the thread would terminate silently. It turns out that this is what this code will do if you attempt to run it in TestDriven.Net. In other words, the test will not fail!



To get this to work the Assert needs to be surrounded by a try/catch block.




var thread = new Thread(SafeAssertBlock);
thread.Start();
thread.Join();

...

public void SafeAssertBlock() {
try {
Assert.NotNull(null);
}
catch (Exception ex) {
// log the exception or pass it back to the owning thread...
}
}



What I eventually settled on was a form like this.




private Exception ThreadsException { get; set; }

...

ExceptionCatcher(() => Assert.Null(ContextScope<string>.GetInstance(ScopeKey)));

...

private void ExceptionCatcher(Action action)
{
try
{
ThreadsException = null;
action();
}
catch (Exception ex)
{
Logger.Error(ex.GetBaseException().Message);
ThreadsException = ex;
}
}



This passes the Assertion block into the ExceptionCatcher, which in turn sets a variable named ThreadsException back in the main thread. If ThreadsException is not null after we make the call then we can log that exception or re-throw it.



So, what happens to xUnit if you attempt to test code that throws an exception in a thread? It turns out that each test is run in its own AppDomain and when the exception is thrown there is an attempt to Serialize the exception. I'm not totally sure, but I believe that communication between AppDomains uses .NET Remoting. In any case, you get an ugly Marshalling exception down in the guts. This may have been helped if the xUnit guys had decided to have their Exception types be Serializable and have the appropriate serialization constructors. Perhaps in a later release?

Thread-specific data and the FreeNamedDataSlot function

First a bit of “context” setting before we proceed. If you’ve ever wanted to store data that is local to a single thread, you have three alternatives depending on your environment. If you’re only inside of a HTTP Web Request, you are in luck as you can set data into the HttpContext.Current.Items and its good for the duration of that web request.

If you happen to be writing any other type of application (Console, Windows Forms, Windows Service, etc…) then you have two alternatives. The easiest is to make a field with the ThreadStaticAttribute. You use this on a static field. With this attribute each thread has its own version of the field. That’s pretty easy!

If you want a little more control (or headaches) then you can use the Thread.GetNamedDataSlot and the Thread.GetData/Thread.SetData methods. What do all these do? Well, GetNamedDataSlot looks for a data slot on the current thread with the name that you pass to the method. If no slot is found it lazily instantiates one for you. The value returned is used as an argument to the GetData and the SetData methods, in other words your getter and setter for accessing thread local data.

BEWARE: There is another static method named FreeNamedDataSlot which you should use with extreme caution or not at all. This will free all of the data slots from each and every thread! The only time this makes sense to use is when you are absolutely sure that there are no threads running that are making use of the named slot you are about to free.

Technorati Tags: ,