Deleting multiple objects with NHibernate using a query

I needed to delete a bunch of objects based on some parameters of those objects. It fairly obvious that one of the Delete overloads on ISession would work, but a couple of things throw me. First you need a full select query, not too hard to figure out. But second, where are IType’s defined? In NHibernateUtil (thanks to this). Anyway, here is some sample code. I’m guessing there might be a more efficient way, but this should work for most cases.



session.Delete(“select b from Bar as b where b.Instrument = :instrument and b.BarMinutes = :barMinutes”,
new object[] {instrument, barMinutes},
new IType[]
{
NHibernateUtil.Entity(typeof (Instrument)),
NHibernateUtil.Enum(typeof (BarMinutes))
});


Update on the AIM bot, new Amazon web services S3 Library

</p>

I’m still working on the AIM Bot, converting from boo to c#. I really liked working in boo, but just don’t feel like I have enough comfort in it to continue working in it. Anyway, I’ve decided to use the Amazon web service S3 for my data storage and have created an open source project, AwsS3Library, to connect to it.

It’s pretty basic so far, listing buckets, and object, and getting, putting, and deleting buckets and objects. The usage isn’t too hard to follow, I’d suggest looking at the unit tests if your stuck. You will need to use your own AWS key and AWS Secret key.

AwsBucket awsBucket = new AwsBucket("bucketName");
AwsS3Service service = new AwsS3Service("AwsKey", "AwsSecret")
awsBucket = service.Put(awsBucket);

There is an intermediate issue with putting objects, which results in a timeout. I think it has to do with trying to put an object right after creating a new bucket. I’m not sure how or if this should be addressed by the library. I’m going to change the tests to create a bucket for the objects and one for testing the bucket functionality. I think that should help.

It’s released under the BSD License to feel free to use and submit fixes.


Race between the If statement and the Delegate Swapping/Substitution Pattern

Which is faster delegate swapping or simple if statements? I wanted to know too and it turns out it’s a tie, as far as I can see. The idea is that you might have some code you want to  execute until some condition occurs then execute some different code. This might be a run once thing or a run until X is true. Either way you could use an if statement. However, many times I prefer to use a delegate, I think it looks better and the code is easier to read. Anyway, I created a small program to test this and here are the results:races

10000:10000 calls using Delegates averaging 0.005937576 seconds.
10000:10000 calls using Ifs       averaging 0.005312568 seconds.
5000:10000 calls using Delegates averaging 0.005156316 seconds.
5000:10000 calls using Ifs       averaging 0.005156316 seconds.
2:10000 calls using Delegates averaging 0.005000064 seconds.
2:10000 calls using Ifs       averaging 0.005156316 seconds.
1:10000 calls using Delegates averaging 0.005000064 seconds.
1:10000 calls using Ifs       averaging 0.005156316 seconds.

I declare a tie because different runs of the program yield slightly different results even though the run times are averaged over 100 runs. The first number is the number of times the TaskOne method is called, the second number is the total number of times the run method was called. Each set was run 100 times for the averaging seconds number.

Pseudo code for the Ifs method:

public void Ifs()
{
if (!TaskOneIsComplete())
TaskOne();
TaskTwo();
}

Pseudo code for the Delegates method:

public void Delegates()
{
_executeMe();
}

private void InitialDelegate()
{
TaskOne();
TaskTwo();

if (TaskOneIsComplete())
_executeMe = AfterDelegate;
}

private void AfterDelegate()
{
TaskTwo();
}

DelegateSubstitutionVSIfStatements.cs (2.96 KB)


Giving up on boo for the AIM bot due to incomplete Generics support.

Well after getting an internal compiler error and trying to find out what the problems was, I decided to see if I could recreate the issue. In doing that, I wanted to know how to set constraints on generic types, and as it turns out this is still in progress as detailed in this post. Oh well, I guess having the AIM bot code in c# will readable by more people anyway. 

I really enjoy working in boo and still have more of the language to explore including Syntactic Macros and Generators.


Using the Prototype Javascript Library to Fix my CSS Layout

I made some tweaks to my blog layout specifically the columns and added a footer. The footer is where the problem started. With CSS using float for the side columns works great and the footer will fall below the main content as long as the main content column is taller then the floating columns. If not, the floating column will float over the footer. To fix this I used the prototype{#hm8i} javascript library to adjust the height of the main column if the floating column is taller. I added a MadKast{#e12e} size constant because the MadKast script will usually load after the height adjustment leaving the main content column short about 25 pixels. Anyway, here’s the code:

<script language="javascript">
<!--
_madKastSize = 25;

Event.observe(window, "load", function() {
if ($('left') && $('left').offsetHeight > $('right').offsetHeight)
$('right').setStyle({height:($('right').offsetTop + $('left').offsetHeight + _madKastSize) + "px"});
});
// --> </script>
</p>

Building an AIM Bot in .Net using boo

I’ve been working on a AIM Bot using the aimcc sdk. After signing up and downloading the sdk from developer.aim.com I found the documentation for .net lacking and found just getting up and running to be a long process. Below are some of the issues I ran into.

**Application.Run()</p>

</b>To start with I needed to create a class which extends Control. Then add a method to start the application, at the beginning of the method call CreateControl() at the end of the method you need to call Application.Run() to setup the message loop. I’m working in boo but this should work fine in c#.

class Bot(Control):
def Start():
CreateControl()
#AccSession setup to go here
Application.Run()

PInvoke

Next pinvoke is required to creat the AccSession instance. This is in some of the SDK samples, but it wasn’t obvious looking at the java and c++ sample bots. It only calls acccore.dll, but other dll’s in the accsdk/dist/release/ are needed I’m just using the full path, but should copy the required dll’s to my project file.



    [DllImport(“C:\accsdk\dist\release\acccore.dll”, EntryPoint:“#111”, PreserveSig:false, SetLastError:true)] 
    private static def AccCreateSession(
    [MarshalAs(UnmanagedType.LPStruct)] riid as Guid,
    [MarshalAs(UnmanagedType.IDispatch)] ref session as object) as IntPtr:
        pass

Calling the method is pretty strait forward, just pass in an object and then cast the object to a AccSession.


CreateControl()
o as object
AccCreateSession(typeof(IAccSession).GUID, o)
session = o as AccSession

</pre>

Login

The next step was to wire up the events I wanted to get catch, I choose to wire up all the events for logging. You need to provide your API key and then login.


handler = AccSessionEventHandler(BoxesImResponder())
handler.WireSession(</em>session)
session.ClientInfo.Property[AccClientInfoProp.AccClientInfoProp_Description] = key
session.Identity = username
session.SignOn(password)
Application.Run()

That’s finally all I needed to get the bot running. I fought with setting preferences for a long while like the java example shows, but I ended up following the c++ example to filter which messages get accepted. More to follow in later posts. In addition, I plan on posting the full source code when the application is working.

</p>

Implied generic parameter types

I’m not sure of the exact name of this feature, but I stumbled across it today. If a generic method uses the type for a parameter, the complier assumes the generic type, which makes for cleaner code.

using System;

class Program
{
static void Main()
{
MyClass.WriteInputStatic("test");
MyClass obj = new MyClass();
obj.WriteInput(12);
}
}

public class MyClass
{
public static void WriteInputStatic<T>(T input) { Console.WriteLine(input); }
public void WriteInput<T>(T input) { Console.WriteLine(input); }
}

I can’t think of many use cases, but kind of a cool feature anyway. I was using it to serialize and deserialize a type for testing the correct serialization/deserialization.

internal static T Serialize<T>(T worker) where T : class
{
    MemoryStream serializationStream = new MemoryStream();
new BinaryFormatter().Serialize(serializationStream, worker);
byte[] bytes = serializationStream.ToArray();

MemoryStream deserializationStream = new MemoryStream(bytes);
object obj = new BinaryFormatter().Deserialize(deserializationStream);
return obj as T;
}
</p>

Overriding component parameters when using Castle.MicroKernel

Overriding component parameters when using the Castle.MicorKernel turned out to be kinda weird. Anyway, here’s one way to do it.

IoC.Container.Kernel.RemoveComponent("ComponentA");
IoC.Container.Kernel.AddComponentInstance(
"ComponentA",
typeof (ComponentA),
new ComponentA("Customer parameter for testing."));

I needed to override the parameter value of ComponentA for some unit tests. The parameter is normally set in the configuration file. After trying a few different approaches, I ended up with the code above. It’s more of an end to end unit test, and as such ComponentA will be resolved as a result of another Component being resolved.


Unit Test Live Templates for ReSharper

Attached are Live templates that can be imported into ReSharper to help with writing unit tests. There are templates for Test, Setup, TearDown, TestFixtureSetUp and TestFixtureTearDown methods.

I find that failing test cases are really good reminders of things that need to get done, so often I will add test methods with Assert.Fail(); as the body, usually the method name is enough detail for me to remember what needs to be done.

Lastly, I’ve started using the ConditionalAttribute on my test class methods so they won’t be compiled in release mode. If this is not your style you may want to modify the templates.

ReSharperUnitTestLiveTemplates.xml (2.63 KB)

**Update:
** I’ve decided against using the ConditionalAttribute in favor of adding compiler directives to the test files. I quickly found that not using the attribute became a source for failing tests that shouldn’t have been run and/or simple code leaks. I know that many people prefer a different class library for tests, but I think that only makes sense for non unit tests. Anyway, here’s the updated file.

ReSharperUnitTestLiveTemplates1.xml (2.48 KB)


Setting up VS 2005 for nant build files

To setup nant intellisense in VS 2005 you can copy the schema from the install to the Visual Studio Install\xml\schema directory, however this won’t get all available tasks. As such, I prefer to create a nant file which calls the nantschema task (http://nant.sourceforge.net/release/0.85/help/tasks/nantschema.html). This task requires an output attribute be set, which I just set to my Visual Studio Install\xml\schema directory. Below is the build script I use:

<?xml version="1.0" encoding="utf-8"?>
<project name="Build nant schema to VS 2005" default="build" basedir=".">
    <target name="build">
        <nantschema 
output="C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas\NAnt.xsd"
target-ns="http://tempuri.org/nant-donotuse.xsd" /> </target> </project>

You can run this after updating Nant or adding contrib projects to your installation and get the latest tasks.

Finally, in your other build files add the xmlns attribute to the project element pointing to the name space you used as the target-ns, http://tempuri.org/nant-donotuse.xsd in the above example. You may also need to tell VS to open .build files with the xml editor, you can do this by right clicking on the .build file and choosing ‘open with’.


Sum a column in a tab-delimited file using Powershell

Assuming you have a bunch of tab delimited files w/out headers and the second column as a number, you could use the following powershell command to sum the values and output the result.

PS > $sum=0; ls | cat | %{ $.split(“`t”)[1] } | %{ $sum+=[int]$ }; $sum

Sample File:

a-count    7
b-count 233
c-count 32
</p>


Reflection.Emit.DeclareLocal and Reflection.Emit.DefineLabel

Working with Reflection.Emit today I ran into two thing that I couldn’t

quickly find answers to. First, was regarding the br.s (OpCodes.Br_S)

code. Secondly, was regarding an error ‘Common Language Runtime

detected an invalid program’ which didn’t provide much help and the

cause was not obvious. After a lot of research and trial and error I

found some answers.

Regarding the first issue, I found this page on MSDN which also show’s

how to create a switch statement.

http://msdn2.microsoft.com/en-us/library/csx7wsz2(vs.80).aspx. The

solution is to create a Label object and MakeLabel method when Emitting

the IL.

Label endOfMethod = il.DefineLabel();
...
il.Emit(OpCodes.Br_S, endOfMethod);
il.MarkLabel(endOfMethod);

The above will create IL like this:

IL_0017:  br.s       IL_001
IL_0019:  ldloc.1

The second problem maybe should have been obvious, but most of what I
read didn’t cover this. If you need to store something you need to
create local storage before trying to store objects there. Not doing
this will result in a System.InvalidProgramException. You need to
create the storage with the il.DeclareLocal method passing in the Type
of the object you will store there.

il.DeclareLocal(stringBuilderType);
il.DeclareLocal(typeof(string));

The above will create IL like:

.locals init (class [mscorlib]System.Text.StringBuilder V_0,
            string V_1)

Working sample command line application (.net2.0) flie – Program.cs.txt (2.45 KB)


Deleting files recursively with PowerShell

This is not the hardest script to come up with, but I can think of a few times I could have used something like this.

ls -rec -inc .svn -fo | foreach {del $_ -rec -fo}</font></pre>


It will delete any file or folder named </em>.svn in the current directory or below.


NHibernate access strategy names

Here are the naming strategies for the NHibernate access attribute.

  • property
  • field
  • field.camelcase
  • field.camelcase-underscore
  • field.pascalcase-m-underscore”
  • field.lowercase-underscore
  • nosetter.camelcase
  • nosetter.camelcase-underscore
  • nosetter.pascalcase-m-underscore
  • nosetter.lowercase-underscore
[Id(Column = “id”, Name = “Id”, 
Type = “Int32”, UnsavedValue = “0”,
Access = “nosetter.camelcase-underscore”),
Generator(1, Class = “native”)]

Switch statement and the goto command.

The goto command can be used to within a switch statement to transfer control to other case statements or the default case statement. Using **goto case ** will transfer control to that case statement. Using **goto default** will transfer execute to the default statement. I’m not sure it produces the cleanest code, but here’s an example anyway.

public void SwitchMe(StatesEnum state) 
{
switch (state)
{
case StatesEnum.Stopped:
Start();
goto case StatesEnum.Starting;
case StatesEnum.Started:
Stop();
goto case StatesEnum.Stopping;
case StatesEnum.Stopping:
state = StatesEnum.Stopping;
goto default;
case StatesEnum.Starting:
state = StatesEnum.Starting;
goto default;
default:
Log(state);
break;
}
}

public enum StatesEnum
{
Stopped,
Starting,
Started,
Stopping
}

So, looking above, if state = Stopped and was passed to the SwitchMe method, the code would execute as follows:

  1. the Stopped case would execute calling the Start method
  2. the Starting case would execute setting the value of state to Starting
  3. the default case would execute calling the Log method

Fully qualified type names for generic types

Syntax for generic types names:

MyAssembly.MyClass`[[MyAssembly.MyOtherClass, MyAssembly]], MyAssembly

Should be able to use this format anywhere a type name is required, including the Inherits attribute on ASPX Page declarations.

</p>

Using AppDomains to run a process outside of the ASP.NET Context

There a few reasons why you might want to run a process in an AppDomain.

For example, if you need to be able to unload and update the loaded

assemblies. Or in my case, use an assembly which actively blocks

execution in your currentAppDomain which may be under the ASP.NET context.

In

this simple example the same security evidence and configuration of the

current domain is used. Further the current assembly happens to be the

one we want to execute, this doesn’t need to be the case however. TheAppDomain.CreateDomain method creates a new AppDomain

and returns a reference to it. This will be used to call create the

processing class and unload the domain when it’s no longer needed.

Next an interface is needed (suggested) for the object that is going to be executed. Here it’s IMyProcess

which defines a Process method. The implementation needs to inherit

from MarshalByRefObject. This allows the framework to handle garbage

collection and life cycle management of the object across the two

domains. Also any object passed across the domain should inherit from

MarshalByRefObject. If the process is really long running, some of the

life cycle properties of MarshalByRefObject will need to be changed.

A

context object is used here to pass data to the processing class, this

isn’t explicitly needed but makes for a little cleaner code. It is also

a MarshalByRefObject. TheCreateInstanceAndUnwrap method creates a proxy

to the specified type and Unwraps it making it usable as if the object

was created in the current domain. The full assembly name, the type

name,BindingFlags, args (for the constructor in this case), CultureInfo, and security evidence need to be passed to the CreateInstanceAndUnwrap

method. The returned object needs to be cast to the Interface type,

done with the as keyword here. Now the Process method of theIMyProcess can be called.

Lastly, the created domain should be unloaded using the AppDomain.Unload method, passing the domain reference from the CreateDomain method. This should be in a finally block to make sure the domain is unloaded. Creating AppDomains

is an expensive process and should be done with this consideration in

mind. Below is most likely not the best way to minimize that expense.



using System;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Security.Policy;

namespace AppDomainSample
{
static class Program
{
[STAThread]
static void Main()
{
Execute(1, "connection...");
Console.ReadKey();
}

public static void Execute(int id, string connectionString)
{
Assembly assembly = Assembly.GetExecutingAssembly();
string assemblyName = assembly.FullName;
string basePath = new Uri(Path.GetDirectoryName(assembly.CodeBase)).LocalPath;

AppDomain currentDomain = AppDomain.CurrentDomain;
Evidence evidence = currentDomain.Evidence;

AppDomainSetup ads = new AppDomainSetup();
ads.ConfigurationFile = currentDomain.SetupInformation.ConfigurationFile;
ads.ApplicationBase = basePath;
ads.PrivateBinPath = basePath;
ads.ShadowCopyFiles = "true";

AppDomain d = AppDomain.CreateDomain("AppDomainSampleName", evidence, ads);
try { MyContext context = new MyContext(id, connectionString);

d.Load(assemblyName);
object[] args = new object[] { context };
IMyProcess r =
d.CreateInstanceAndUnwrap(assemblyName, "AppDomainSample.MyProcessImpl", false,
BindingFlags.CreateInstance, null, args, CultureInfo.CurrentCulture, null, evidence) as IMyProcess; r.Process(); } finally { AppDomain.Unload(d); } } } internal class MyProcessImpl : MarshalByRefObject, IMyProcess
{
private readonly MyContext _context;

public MyProcessImpl(MyContext context)
{
_context = context;
}

public void Process()
{
Console.WriteLine("ConnectionString: {0} from {1} domain.", _context.ConnectionString,
AppDomain.CurrentDomain.FriendlyName);
}
}

internal interface IMyProcess
{
void Process();
}

internal class MyContext : MarshalByRefObject
{
private readonly int _id;
private readonly string _connectionString;

public MyContext(int id, string connectionString)
{
_id = id;
_connectionString = connectionString;
}

public int Id
{
get { return _id; }
}

public string ConnectionString
{
get { return _connectionString; }
}
}
}

Initializing excel for use from a service account

Sometimes you need to use excel automation and you’d like to have your service or web application running under an service account identity. In some cases excel wants to run some setup on first use by an account. One way is to log into the machine using that account and open excel. A quicker way is to use the following command.

C:\Program Files\Microsoft Office\OFFICE11>runas /user:MyServiceAcct excel.exe

Embedded Databases

I needed an embeddable database to handle some processing before

inserting the data into the final database. I worked with three

different embeddable databases, each had some pros and cons.

SQL Server Everywhere/Mobile edition

SQL Server Everywhere

is a free embeddable database from Microsoft, formally SQL CE. It’s

small, fast and offers almost full support for T-SQL. One thing that it

doesn’t support is square brackets for escaping names. Also, no support

for stored procedures, which wasn’t a concern for this project. The

main problem was that it will throw an exception if it’s running under

IIS. It’s obvious from the documentation that running under IIS is not a supported

environment, but there are some cases where it could provide a good

solution. I worked around this using app domains, which I’ll post about

later. It can be used with SQL Server replication which could be a hugely useful feature.

Being a MS product it has a fully supported .net provider and is supported on Mobile devices.

Embeddable Firebird

Firebird was

easy to setup and get going, but it does have one very annoying quirk.

It uppercases names by default and it doesn’t accept square brackets

for escaping names, but does accept single quotes. Also, it is case

sensitive so if you use them then you always have to use them unless

your names are uppercase. For example select * from ‘mytable’ is not the

same as select * from ‘MyTable’. And if you create a table with create

table mytable it will create a table named MYTABLE and selects will

need to select from MYTABLE not mytable. I don’t know if I explained

this clearly, but it is a weird quirk. This may be changed in version 2

which I don’t think has an embedded version yet, but could be a very good DB if this quirk was addressed.

The download section has the embeddable version and a .net provider.

Sqlite

Sqlite was also

very easy to get working and worked well for smaller data sets. Using

an index column or having a lot of data rows (10,000+) and things started

to really slow down. It could have been that I didn’t have something

setup correctly, but regardless it was performing really slowly. Setting up a auto

incrementing primary key was a bit tricky, the syntax is below. I don’t

see any advantage to this over SQL Server Everywhere, except that it’s

open source, it may also support stored procedures, but I’m not sure.

create table mytable (id integer primary key)…

The System.Data.Sqlite

project offers the Sqlite DB and a .net provider in one merged managed DLL, which makes

for a very clean distribution. Also, provides Mobile development

support.

All in all, I liked SQL Server Everywhere the best, it has really good

performance a small footprint and a familiar syntax if you’re used to

SQL Server.</p>


Castle monorail logging with windsor

Using Castle monorail with windsor, I setup the logging facility and followed the IoC of concept parameters for optional components. I noticed the base Controller had Logger property and assumed that windsor would handle it from there. However, my controller always had the NullLogger as the ILogger property. The base Controller class doesn’t have a setter for the Logger property. Still not sure why that is, also the property is not virtual. I should submit a patch for this. Anyway, one solution is to create a new property Logger in your own Controller with a getter and setter thus allowing windsor to set the Logger when the Controller is created.

public abstract class BaseSiteController : ARSmartDispatcherController
{
private ILogger _logger = new NullLogger();

public new virtual ILogger Logger {
get { return _logger; }
set { _logger = value; }
}
}
</p>

SharpDevelop project templates

I wanted to create castle project template for SharpDevelop, I ran into a few issues, some I found a way to fix, some I didn’t.

One thing that I needed to do was add a project reference to a dll that was not in the GAC, to do this the HintPath attribute can be used on the Reference element.

    <Reference Include=“Castle.Core” HintPath=“c:\castlebin\Castle.Core.dll”/>

Secondly, I wanted to set the debug options to allow cassini debugging. I found a way to set these options but I didn’t find a way to dynamically insert the project name/dll into the command line options. In the PropertyGroup element you can add the following to set these options. Note the ${ProjectName} string is not replaced with the project name.

    <DebugOptions>
        <StartAction>Program</StartAction>
        <StartProgram>c:\program files\cassini\CassiniWebServer2.exe</StartProgram>
        <StartArguments>C:\Documents and Settings\Dusty\My Documents\SharpDevelop Projects\${ProjectName} 8080 “/${ProjectName}”</StartArguments>
    </DebugOptions>

So I guess there are still two main problems with this setup. First you have to know the path of any dll’s that are not installed in the GAC. And if you want to reference the project name in the debug options, it doesn’t look like there is a way to do that. But for setting up personal project templates these things may be useful.


Setting build numbers with Nant

    <h3> Setting build numbers with Nant </h3> I wanted something that would update the version number of my builds from within Nant. I found that using some of the built in functions of Nant I could get what I wanted without too much work. Nothing really exciting here, but a couple of notes. First the version numbers stored in the meta data limit the size to uint16.maxvalue - 1 so the value must be less then 65534. As such I could not use the format yyyyMMdd as I wanted to, so I ended up using days since 1/1/2000. Secondly, when loading the file with loadfile I needed to mark the encoding as UTF-8 so that the file would be writen back out in a usable form. Anyway, here's the nant code I ended up using.<br /><pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.major"</span><span class="attr"> value</span><span class="kwrd">="0"</span><span class="kwrd">/&gt;</span><span class="kwrd"><br />&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.minor"</span><span class="attr"> value</span><span class="kwrd">="9"</span><span class="kwrd">/&gt;</span><span class="kwrd"><br />&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.build"</span><span class="attr"> value</span><span class="kwrd">="${timespan::get-days(datetime::now() - datetime::parse('01/01/2000'))}"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.revision"</span><span class="attr"> value</span><span class="kwrd">="0"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.version"</span><span class="attr"> value</span><span class="kwrd">="${build.major}.${build.minor}.${build.build}.${build.revision}"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">foreach</span><span class="attr"> item</span><span class="kwrd">="File"</span><span class="attr"> property</span><span class="kwrd">="assemblyinfofile"</span><span class="kwrd">&gt;</span><br />  <span class="kwrd">&lt;</span><span class="html">in</span><span class="kwrd">&gt;<br /></span>    <span class="kwrd">&lt;</span><span class="html">items</span><span class="attr"> basedir</span><span class="kwrd">="${project.root}"</span><span class="kwrd">&gt;<br /></span>      <span class="kwrd">&lt;</span><span class="html">include</span><span class="attr"> name</span><span class="kwrd">="**\AssemblyInfo.cs"</span><span class="kwrd">/&gt;<br /></span>    <span class="kwrd">&lt;/</span><span class="html">items</span><span class="kwrd">&gt;</span><br />  <span class="kwrd">&lt;/</span><span class="html">in</span><span class="kwrd">&gt;</span><br />  <span class="kwrd">&lt;</span><span class="html">do</span><span class="kwrd">&gt;<br /></span>    <span class="kwrd">&lt;</span><span class="html">echo</span><span class="attr"> message</span><span class="kwrd">="${path::get-file-name(assemblyinfofile)}"</span><span class="kwrd">/&gt;<br /></span>    <span class="kwrd">&lt;</span><span class="html">loadfile </span><span class="attr">file</span><span class="kwrd">="${assemblyinfofile}"</span><span class="attr">property</span><span class="kwrd">="assemblyinfofile.content"</span><span class="attr">encoding</span><span class="kwrd">="utf-8"</span><span class="kwrd">/&gt;</span><br />    <span class="kwrd">&lt;</span><span class="html">regex</span><span class="attr"> pattern</span><span class="kwrd">="&amp;quot;(?'version'\d+\.\d+\.\d+\.\d+|\d+\.\d+\.\*)&amp;quot;" </span><span class="attr">input</span><span class="kwrd">="${assemblyinfofile.content}"</span><span class="kwrd">/&gt;</span><br />    <span class="kwrd">&lt;</span><span class="html">echo</span><span class="attr"> file</span><span class="kwrd">="${assemblyinfofile}"</span><span class="kwrd">&gt;</span>${string::replace(assemblyinfofile.content, version, build.version)}<span class="kwrd">&lt;/</span><span class="html">echo</span><span class="kwrd">&gt;</span><br />    <span class="kwrd">&lt;</span><span class="html">echo</span><span class="attr"> message</span>="<span class="attr">-</span><span class="kwrd">&gt;</span> Updated version from ${version} to ${build.version}"<span class="kwrd">/&gt;<br /></span>  <span class="kwrd">&lt;/</span><span class="html">do</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">foreach</span><span class="kwrd">&gt;</span></pre><div style="clear: both; padding-bottom: 0.25em;"></div>

Monorail: Exception Handlers: Flash and Redirect

e setting up exception chaining on monorail, I wanted to use the Flash properties to store the LastException for next request, an error page. This by default doesn't work if the exception happens outside of the Castle.MonoRail.Framework.MonoRailHttpHandler.Process method. This is because the Flash variables don't get saved until after this method. One note here, the Process method is wrapped in a try, finally block and the Flash properties will be saved in the case of an exception on the Process method, some additional checking in the exception handler may be needed to catch this. Anyway, I added the following line to my last handler and the Flash properties are working great.<br /><br /><span style="font-family: Courier New;">context.Session[Flash.FlashKey] = context.Flash;</span><br /><br /> Secondly, I wanted to redirect to different views based on the exception, which I wasn't able to do. The reason was that the asp.net framework noticed the exception an handled according, not what I wanted. The way around this is to clear the error using the Server.ClearError() method before redirecting.<br /><br /><span style="font-family: Courier New;">context.UnderlyingContext.Server.ClearError();</span><br /><div style="clear: both; padding-bottom: 0.25em;"></div>

Using nant and tallow to create usable WIX component.

    <p>Creating installer for web application can be a pain, but using tallow and an nant script element can make things a lot easier.</p>
    <p>Once my nant script was building my solution and web project with all the needed output files I begin to setup automating the build of the WIX component for the web application.</p>
    <p>As you know tallow output is not usable as is, some custom handling needs to be done. I've found the script element of nant to work well for this. I've also created a new class library project to keep the script block small, and keep the source in a project. I've included the class library in the solution build. </p>
    <p>Nant target:</p>
    <!-- code formatted by http://manoli.net/csharpformat/ -->
    <pre class="csharpcode">&lt;property name="wix.websitefragment.file" value="${build.output.temp}\website-fragment.wsx"/&gt;<br />&lt;target name="buildwebsitewsx" depends="solution"&gt;<br />    &lt;mkdir dir="${build.output.temp}"/&gt;<br />    &lt;exec program="${wix.bin}\tallow.exe" workingdir="${build.output.temp}" output="${wix.websitefragment.file}"&gt;<br />        &lt;arg value="-d &amp;quot;${compile.output.webapplication}&amp;quot;"/&gt;<br />        &lt;arg value="-nologo"/&gt;<br />    &lt;/exec&gt;<br />    &lt;script language="C#" verbose="true"&gt;<br />        &lt;references&gt;<br />            &lt;include name="${compile.output}\InstallHelper.dll"/&gt;<br />        &lt;/references&gt;<br />        &lt;imports&gt;<br />            &lt;import namespace="InstallHelper"/&gt;<br />        &lt;/imports&gt;<br />        &lt;code&gt;<br />        &lt;![CDATA[<br />        public static void ScriptMain(Project project) {<br />            string file = project.Properties["wix.websitefragment.file"];<br />            new FixTallow(file, "My.ComponentGroup.Name").UpdateFile();<br />        }<br />        ]]&gt;<br />        &lt;/code&gt;<br />    &lt;/script&gt;<br />&lt;/target&gt;<span class="kwrd"></span></pre>
    This calls the tallow application on the directory where the web application is built. Then loads and calls the InstallHelper.dll to modify the tallow output into something more usable. <br /><p>The FixTallow class loads the tallow output into an XML document and takes the following actions; adds a component group, creates guids for the components, renames the directory id's and changes the directoryRef element to point to the INSTALLDIR.</p><p>The component group needs to be created so a reference can be added to the main WIX file. This is because tallow creates a component for each directory (or each file) and because I don't want to update the main WIX file every time there is a directory added or removed from the web application. The group name is passed the the constructor of the FixTallow class. </p><p>FixTallow also renames the directory id's so that I can reference them if needed from the main WIX file, however if the directory is removed or renamed, the main WIX file will need to be updated. Also, the root DirectoryRef element is changed to reference INSTALLDIR which needs to be set in the main WIX file. This is a good idea as it allows the installation directory to be changed when installing.</p><p>FixTallow.cs</p><pre class="csharpcode"><span class="kwrd">    public</span><span class="kwrd">class</span> FixTallow<br />    {<br /><span class="kwrd">  private</span><span class="kwrd">readonly</span><span class="kwrd">string</span> _filename;<br /><span class="kwrd">    private</span><span class="kwrd">readonly</span><span class="kwrd">string</span> _componentGroupName;<br />        XmlDocument _document = <span class="kwrd">new</span> XmlDocument();<br />        XmlNamespaceManager _manager;<br />        XmlElement _compGroup;<br /><br /><span class="kwrd">   public</span> FixTallow(<span class="kwrd">string</span> filename, <span class="kwrd">string</span> componentGroupName)<br />        {<br />            _filename = filename;<br />            _componentGroupName = componentGroupName;<br /><br />            _manager = <span class="kwrd">new</span> XmlNamespaceManager(_document.NameTable);<br />            _manager.AddNamespace(<span class="kwrd">string</span>.Empty, <span class="str">"http://schemas.microsoft.com/wix/2003/01/wi"</span>);<br />            _manager.AddNamespace(<span class="str">"ns"</span>, <span class="str">"http://schemas.microsoft.com/wix/2003/01/wi"</span>);<br />        }<br /><br /><span class="kwrd"> public</span> FixTallow UpdateFile()<br />        {<br />            _document.Load(_filename);<br /><br />            AppendComponentGroupElement();<br /><br /><span class="kwrd">        foreach</span> (XmlElement element <span class="kwrd">in</span> _document.SelectNodes(<span class="str">"//ns:Component"</span>, _manager))<br />            {<br />                element.Attributes[<span class="str">"Guid"</span>].Value = Guid.NewGuid().ToString().ToUpper();<br />                AppendComponentToGroup(element.Attributes[<span class="str">"Id"</span>].Value);<br />            }<br /><br />            ChangeDirectoryRefId();<br /><br />            UpdateDirectoryIds();<br /><br />            _document.Save(_filename);<br /><br /><span class="kwrd">      return</span><span class="kwrd">this</span>;<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> UpdateDirectoryIds()<br />        {<br /><span class="kwrd">            foreach</span> (XmlElement directory <span class="kwrd">in</span> _document.SelectNodes(<span class="str">"//ns:Directory"</span>, _manager))<br />            {<br /><span class="kwrd">                string</span> directoryName = (directory.Attributes[<span class="str">"LongName"</span>] == <span class="kwrd">null</span>)<br />                                           ?<br />                                       directory.Attributes[<span class="str">"Name"</span>].Value<br />                                           :<br />                                       directory.Attributes[<span class="str">"LongName"</span>].Value;<br />                directory.Attributes[<span class="str">"Id"</span>].Value = directoryName + <span class="str">".Dir"</span>;<br />            }<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> ChangeDirectoryRefId()<br />        {<br />            _document.SelectSingleNode(<span class="str">"/ns:Wix/ns:Fragment/ns:DirectoryRef/@Id"</span>, _manager).Value = <span class="str">"INSTALLDIR"</span>;<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> AppendComponentToGroup(<span class="kwrd">string</span> componentId)<br />        {<br />            XmlElement componentRef = _document.CreateElement(<span class="str">"ComponentRef"</span>, _manager.DefaultNamespace);<br />            XmlAttribute componentRefId = _document.CreateAttribute(<span class="str">"Id"</span>);<br />            componentRefId.Value = componentId;<br />            componentRef.Attributes.Append(componentRefId);<br />            _compGroup.AppendChild(componentRef);<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> AppendComponentGroupElement()<br />        {<br />            _compGroup = _document.CreateElement(<span class="str">"ComponentGroup"</span>, _manager.DefaultNamespace);<br />            XmlAttribute compGroupId = _document.CreateAttribute(<span class="str">"Id"</span>);<br />            compGroupId.Value = _componentGroupName;<br />            _compGroup.Attributes.Append(compGroupId);<br />            _document.SelectSingleNode(<span class="str">"/ns:Wix/ns:Fragment"</span>, _manager).AppendChild(_compGroup);<br />        }<br />    }</pre><p>The main WIX file needs to include a few things for this to work. First, it much have a diretory element with INSTALLDIR as it's Id. Second, a ComponentGroupRef element pointing the component group name specified in the FixTallow constructor needs to be included in the Feature element.</p><pre class="csharpcode">...<br /><span class="kwrd">&lt;</span><span class="html">Directory</span><span class="attr">Id</span><span class="kwrd">="TARGETDIR"</span><span class="attr">Name</span><span class="kwrd">="SourceDir"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">Directory</span><span class="attr">Id</span><span class="kwrd">="ProgramFilesFolder"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">Directory</span><span class="attr">Id</span><span class="kwrd">="INSTALLDIR"</span><span class="attr">Name</span><span class="kwrd">="myapp"</span><span class="attr">LongName</span><span class="kwrd">="MyApplicationName"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Directory</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Directory</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Directory</span><span class="kwrd">&gt;</span><br />...<br /><span class="kwrd">&lt;</span><span class="html">Feature</span><span class="attr">Id</span><span class="kwrd">="Complete"</span><span class="attr">Level</span><span class="kwrd">="1"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">ComponentGroupRef</span><span class="attr">Id</span><span class="kwrd">="My.ComponentGroup.Name"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Feature</span><span class="kwrd">&gt;</span><br />...</pre>Lastly, the tallow output needs to be passed to the candle and light applications when building the msi file with something like this:<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">exec</span><br /><span class="attr">program</span><span class="kwrd">="${wix.bin}\candle.exe"</span><br /><span class="attr">workingdir</span><span class="kwrd">="${build.output.install}"</span><br /><span class="attr">commandline</span><span class="kwrd">="Main.wsx website-fragment.wsx"</span><span class="kwrd">/&gt;</span><br />...<br /><span class="kwrd">&lt;</span><span class="html">exec</span><br /><span class="attr">program</span><span class="kwrd">="${wix.bin}\light.exe"</span><br /><span class="attr">workingdir</span><span class="kwrd">="${build.output.install}"</span><br /><span class="attr">commandline</span><span class="kwrd">="-out MyApplication.msi Main.wixobj website-fragment.wixobj"</span><span class="kwrd">/&gt;</span></pre><span class="kwrd">There was a lot of setup here, but once completed changes can be made to the web application without modifying the WIX files, resulting in an up to date MSI on each build.</span><br /><div style="clear: both; padding-bottom: 0.25em;"></div>

Brutalist Framework