Friday, 30 November 2007

Reflecting on JavaScript objects

I have been doing some more playing around with JavaScript recently, and wanted to do some reflection over JavaScript objects to see what functions they had, and then execute some of those functions. This is made fairly easy for us due to JavaScript's use of associative arrays (from Wikipedia's exampleobj.x = 10; is the same as obj["x"] = 10;).

First let's embed some JavaScript into a local HTML file:

<script>
  var MyClass = function() {}
  MyClass.prototype = {
    aFunction: function() { return 1; },
    anotherFunction: function() { return 2; }        
  }
</script>

Here we have a basic MyClass class. We can use the for..in statement to enumerate through the items in this class:

for (var member in MyClass) {
  document.write(member + "<br/>");        
}

This writes "prototype" (plus line break) to the page in FireFox (not in IE7, but haven't looked into why), which is the only thing defined for MyClass. You can also enumerate over MyClass.prototype to see what's there. In my case I wanted to check and run methods from an instance of MyClass (which is initialised from the prototype):

var instanceOfMyClass = new MyClass();
for (var member in instanceOfMyClass) {
 document.write(member);
 document.write(": " + instanceOfMyClass[member]());
 document.write("<br/>");
}                 

Which displays the following (in both FireFox and IE7):

aFunction: 1
anotherFunction: 2

Here we access the functions in instanceOfMyClass by looking up the value associated with each member. One quick gotcha: the for..in enumeration in this case returns strings, not pointers to the member itself (so you can't use member() to evaluate it).

Another option is to use the eval function to execute the method, but that isn't quite as pretty as it involves building up strings (eval("instanceOfMyClass." + member + "()")).

Note we aren't accounting for argument lists here. You might want to look at the Function class for getting more data about functions and their arguments. We also are not catering for members that are not functions. You can use typeof to filter out other values.

Plans for IIS 7.0 web app deployment framework

Just reading through ScottGu's .NET Web Product Roadmap and noticed this (emphasis mine):

"We will also shortly begin sharing details of a new web application deployment framework for IIS that enables you to easily automate the deployment of web applications on either a single server or across a web farm of machines.  It will make it easy to version your web applications (including allowing you to quickly roll back to previous versions), as well as automatically provision them across multiple servers.  It also enables the full automation of deployment tasks (including via both command-line and PowerShell scripting APIs)."

This sounds like much more fun that other approaches I have tried.

ScottGu also mentions that the first public preview of ASP.NET 3.5 Extensions (including ASP.NET MVC) will be released next week! Woohoo! More toys! :-)

Wednesday, 21 November 2007

Link: Mounting ISO images in a virtual CD-ROM drive

I end up looking for this link once or twice every year, so I have finally given in and am chucking on my blog for safe keeping :) 

Mounting ISO images in a virtual CD-ROM drive - help.net

Monday, 19 November 2007

Happy anniversary to me!

I just realised I have been blogging for a year. I wasn't sure what to expect when I started, but I have ended up really enjoying it, pumping out 189 posts to date, some of which are hopefully not pure drivel. I thought I'd post a quick summary to celebrate in a moment of self-indulgence. :-)

When I started blogging my main purpose was to just store some information that I found in other blogs. Basically just more advanced bookmarks. Once I started I noticed there were other benefits, so I have revised my motivations a bit. 

My main purpose for blogging has shifted to using it as a personal tool for learning. I find by explaining concepts I am learning or using to an imagined audience I get a much better understanding of the concepts. There is a big difference between being able to apply a concept and being able to explain it. My secondary purpose is related to my original purpose, to record information that I might need later. And my final hope is that some of that information will be useful to some other developers out there that stumble across my blog.

Since counting stats in August (I reset the stats then) I have had around a thousand visitors stumble across my little patch of the Internet which is nice, as I haven't been promoting it or anything. I toyed with the idea of submitting stuff to DotNetKicks, but when it comes down to it I am really just blogging for me. If someone finds something they need in here via Google then great! I hope you found something that helped!

My most viewed posts to date are:

Over the next year I'm hoping to really improve the technical articles in my blog. I am getting to do loads of development in my current role that gives me lots of opportunities for learning/blogging, as well as getting a bit more free time to research and experiment now that my eldest daughter is heading off to "big school" and probably won't want her old man hanging around embarrassing her anymore ;-).

To all my former colleagues that I forced to subscribe, looks like you'll have to put up with at least another 12 months of nonsense being spewed from my feed. And don't even think about unsubscribing -- I know where you work! :-)

"There are no smart guys, there's only us"

Today's post is dedicated to El# (hi mate! :-) ), with whom I have had many conversations about this topic, with both of us facing the same issue from time to time. I've often talked about the quote from Jeremy Miller that titles this post, but I finally stumbled over the original source the other day:

Thoughts, Rants and Arguments: My DevTeach 2007 Rollup (search for "there are no smart guys" for the relevant paragraph)

I've sometimes been stymied by the thought that I just don't know enough to make a decision on a topic, and that I need to run it through a gauntlet of experts to get "the answer". This has bitten me when it came to introducing TDD, MVC/MVP web development, ORM, refactoring and other practices. I know the benefits, but how can I be confident enough to introduce one of these approaches without fully understanding the entire body of research on the subject, and without having an ironclad guarantee that it will work within a specific environment? I need to talk to the smart guys! I need "the experts"!

There is a big problem (ok, probably several problems) with this attitude. No one, not even the smart guys or the experts, knows "the answer". Generally there isn't "the answer" -- there are just a whole lot of options, some of which suck less than the others (and you won't know which is which without hindsight). There are no smart guys that know "the answer" and can solve all the problems, there's only us, so just make the best decisions you can as a professional. Some decisions will work and some won't, but don't expect anyone else to necessarily be any better in the same situation. As Jeremy Miller put it:

  1. No one's infallible and all knowing
  2. Don't sell yourself short compared to other people

Chances are the smart guys and experts we look up to and whose blogs we read are just the same as us. Maybe the only difference is that they are willing to take the chances, to risk failure, and to learn from everything. It's that kind of experience that makes you the smart guy or gal. If you want to be an expert, take exactly what you are doing right now and try some of the things that you previously were waiting on expert-approval for. Learn from it. Share it with your team or user group. Blog about it. As a former colleague of mine wrote (hi Hassan!), don't be afraid to make mistakes.

JP has had a number of recent posts related to these ideas, from the perspective of a well-respected expert, MVP, code jedi, superhero etc. To quote one of these:

(IsABlogger() && HasAnMVP() && HasDoneLotsOfPresentations()) != IsAnExpert()

By the way, none of this applies to ScottGu, who actually IS a smart guy and expert and should be deferred to at all times ;) (I'm being dead serious btw. How the heck does that bloke get across so much, and still have time to bag out Scott Bellware? :))

None of this is an excuse to make rash decisions or take uncalculated risks. It simply means that if you have put some work into an idea and genuinely believe it has legs, then run with it and see how it goes. Don't wait for the smart guys or the experts to validate it or give you the right answer. They're not coming. You all we've got. And you'll do fine :-)

Update 2008-02-07: Geoff Slinker has a fantastic post on a related note.

Friday, 16 November 2007

Links to LINQ: Writing custom providers

Just storing a couple of links for a rainy day:

Thursday, 15 November 2007

The Illustrated Catalog Of ACME Products

Somehow* I ended up here:

The ORIGINAL Illustrated Catalog Of ACME Products

Great site for all your ACME product needs. Ah, the memories :-) 

* Reading jdn's post on the ALTNETCONF list for acquiring a Bellware translator, which referenced the Wikipedia article which linked to the catalog.

Wednesday, 14 November 2007

Locating NHibernate Mapping Files

I have an assembly full of data objects (say, MyGreatApp.Objects.dll), and an assembly that manages data access (say, MyGreatApp.DataAccess.dll). As the data access DLL is handling persistence, it should have the embedded NHibernate mapping files (*.hbm.xml). I tried to configure a session factory from MyGreatApp.DataAccess.dll like this:

Configuration config = new Configuration();
config.AddClass(typeof(MyGreatApp.Objects.Widget));
SessionFactory = config.BuildSessionFactory();

I thought this would search the current assembly for the Widget.hbm.xml file, and possible the assembly containing the referenced type as well. I was quickly proved wrong as it threw NHibernate.MappingException: Resource not found. NHibernate is only looking for the Widget mapping file in the same place as the type itself, which is MyGreatApp.Objects.dll. Instead we just need to explicitly add the assembly that contains the embedded mapping files:

Configuration config = new Configuration();
config.AddAssembly("MyGreatApp.DataAccess");
SessionFactory = config.BuildSessionFactory();

And this works great! I noticed Jim Holmes is years ahead of me here, but I didn't have much Google-luck with my initial choice of keywords and so thought I'd post my experience.

Thursday, 8 November 2007

LINQ-to-SQL logging via DataContext.Log

After playing around with LINQ-to-SQL today I noticed that the generated DataContext subclass exposes a Log property of type TextWriter.

I initially replaced this with a StringWriter backed by a local StringBuilder variable so I could read the output, but then decided to take advantage of the fact that the generated class is a partial class:

//Generated class: WidgetDb.designer.cs
public partial class WidgetDbDataContext : System.Data.Linq.DataContext {
  ...
}

//My partial implementation: WidgetDbDataContext.cs
public partial class WidgetDbDataContext {
  private StringBuilder logBuilder = new StringBuilder();
  
  public String GetLoggedInformation() {
    return logBuilder.ToString();
  }

  partial void OnCreated() {
    Log = new StringWriter(logBuilder);
  }
}

I could then perform a sample query or two in my ASPX:

private void doLinqStuff() {
  WidgetDbDataContext db = new WidgetDbDataContext();      
  var widgets = from w in db.Widgets select w;
  WidgetGrid.DataSource = widgets;
  WidgetGrid.DataBind();      
  WidgetCount.Text = widgets.Count().ToString();      
  StatusLog.Text += db.GetLoggedInformation().Replace("\n", "<br/>");
}

The output of StatusLog.Text from this was:

SELECT [t0].[WidgetId], [t0].[WidgetName], [t0].[WidgetDescription], [t0].[WidgetPrice], [t0].[IsActive]
FROM [dbo].[Widgets] AS [t0]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1

SELECT COUNT(*) AS [value]
FROM [dbo].[Widgets] AS [t0]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1 

This is potentially helpful for learning how your expressions translate to SQL, but you probably wouldn't want to do this in production :)

I then decided to search Google for "DataContext.Log" and found out that people far smarter than me have already come up with better solutions. Ah well, at least I learnt about extending the generated DataContext, as well as some smart ways of logging from others. :)

Wednesday, 7 November 2007

Windows Live Writer out of beta

The Windows Live suite is out of beta, including Windows Live Writer 2008.

I love Writer :)

Update 2008-01-08: If you are having trouble installing with the new Live installer, try these steps.

Enterprise-scale Reuse - An Illustrated Example

Jason Gorman has an example of how reuse sometimes (typically?) works within enterprises and in some platforms: 

Enterprise-scale Reuse - An Illustrated Example - Agile Software Process Improvement

Cost of compliance is everything. Saving 10 minutes every time someone implements a data entry form is great. Causing an additional three weeks spent debugging a black box and complying with the requirements of the service or platform is significantly less great.

LINQ, deferred execution and closures

Reading Anders' post on Lexical Closures, Deferred Execution and Kicker Methods with respect to LINQ and Quaere, I thought I would write some notes since VS 2008 is RTM this month and I'll hopefully get to start doing some more LINQing.

I have used Anders' example. What result is printed?

int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int i = 1;
var numbersPlusI = from n in numbers
                   select n + i;
i++;
foreach (var n in numbersPlusI) {
  Console.Write(n);
  Console.Write(" ");
}

To make the answer more obvious, let's rewrite without the layer of syntactic sugar. As I don't have .NET 3.5 handy on this PC, this is just an approximation built on .NET 2.0:

int[] numbers = new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 
int i = 1;
IEnumerable<int> numbersPlusI = 
  Enumerable.Select<int>(numbers, delegate(int n) { return n + i; } );
i++;
foreach (int n in numbersPlusI) {
  Console.WriteLine(n);
  Console.Write(" ");
}

LINQ builds up an expression for numbersPlusI, but doesn't execute it until the result is enumerated. Now remembering that C# has closures, the delegate binds to the local variable i (not its value at the point of declaration). When the enumeration is being performed, the delegate is called using i, which is 2 at the time of execution (i=1; i++). So we get:

2 3 4 5 6 7 8 9 10 11 

If you want to run the code on .NET 2.0, here is my approximation of System.Linq.Enumerable and the Func<> delegate relevant for the example. Probably not brilliant, but I am really aiming to illustrate how variables a captured by closures in C#.

public delegate T Func<T, A>(A a);
public class Enumerable {
  public static IEnumerable<T> Select<T>(IEnumerable<T> source, Func<T,T> valueFromSource) {
    foreach (T value in source) {
      yield return valueFromSource(value);
    }
  }
}

Some good references on this:

Thursday, 1 November 2007

Getting SubSonic talking to Oracle

I wasn't sure how well SubSonic would play with Oracle, but it turns out that it was very easy to get the basics working. First, I setup a data access class and the SubSonic basics like VS external tools etc.

Instead of the configuration suggested in the above link, my App.config looked like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="SubSonicService" type="SubSonic.SubSonicSection, SubSonic" requirePermission="false"/>
  </configSections>
  <connectionStrings>
    <clear/>
    <add name="MyAppsConnectionString" providerName="Oracle.DataAccess"
      connectionString="Data Source=MyOracleServer;User Id=MyUserId;Password=MyPassword;Integrated Security=no;" />
  </connectionStrings>
  <SubSonicService defaultProvider="MyApp">
    <providers>
      <clear/>
      <add name="MyApp" type="SubSonic.OracleDataProvider, SubSonic"
        connectionStringName="MyAppsConnectionString"  generatedNamespace="MyApp.DataAccess" />
    </providers>
  </SubSonicService>
</configuration>

The emphasised bits will vary for you obviously. If you need connection string help check ConnectionStrings.com for your Oracle provider. I am using Oracle Data Provider for .NET, so your providerName may vary if you are using a different one.

It was then just a matter of running Sonic.exe generate /out Generated via the external tool configured earlier (or manually running it) from the project directory, and out pops your data access layer.

Double dispatch

Jeremy Miller recently had a post that mentioned "double dispatch", and I had to delve down into the dusty recesses of my at-best-mediocre brain to come up with a definition. Chances are everyone has come across double dispatch in one form or another, and understands it implicitly. However I find it harder to articulate the definition explicitly.

My (admittedly limited) understanding of double dispatch is that it chooses a method to evaluate based on the runtime types of two objects. Also, C# does not support double dispatch, but you can emulate it a number of ways by doing reflection tricks or by using a Visitor-pattern style approach. To illustrate the limitations in C#, I'll borrow the example from Wikipedia and collide some asteroids with spaceships.

[TestFixture]
public class DispatchBehaviour {
  public class SpaceShip { }
  public class GiantSpaceShip : SpaceShip { }
  public class Asteroid {
    public virtual String CollideWith(SpaceShip ship) {
      return "Asteroid hit a SpaceShip";
    }
    public virtual String CollideWith(GiantSpaceShip ship) {
      return "Asteroid hit a GiantSpaceShip";
    }
  }
  public class ExplodingAsteroid : Asteroid {
    public override string CollideWith(SpaceShip ship) {
      return "ExplodingAsteroid hit a SpaceShip";
    }
    public override string CollideWith(GiantSpaceShip ship) {
      return "ExplodingAsteroid hit a GiantSpaceShip";
    }
  }
  [Test]
  public void TestFailsWhenTryingDoubleDispatch() {
    SpaceShip ship = new SpaceShip();
    SpaceShip giantShip = new GiantSpaceShip();
    Asteroid asteroid = new Asteroid();
    Asteroid explodingAsteroid = new ExplodingAsteroid();
    Assert.That(asteroid.CollideWith(ship), Is.EqualTo("Asteroid hit a SpaceShip"));
    Assert.That(explodingAsteroid.CollideWith(ship), Is.EqualTo("ExplodingAsteroid hit a SpaceShip"));
    //This assertion fails:
    Assert.That(explodingAsteroid.CollideWith(giantShip), Is.EqualTo("ExplodingAsteroid hit a GiantSpaceShip"));
 
  }
}

The explodingAsteroid reference looks up the correct virtual function in the ExplodingAsteroid class despite it being referenced via the Asteroid type, thanks to polymorphism and virtual functions. But because C# uses single dispatch, the above test fails because based on the compile-time lookup of the giantShip reference (which is a SpaceShip reference at compile-time). If it where doing that lookup at run-time we'd have a different story.

One way of dealing with this is to switch on the type within the CollideWith methods.

public class ExplodingAsteroid : Asteroid {
  public override string CollideWith(SpaceShip ship) {
    if (ship is GiantSpaceShip) {
      return "ExplodingAsteroid hit a GiantSpaceShip";
    } else {
      return "ExplodingAsteroid hit a SpaceShip";
    }
  }
}
//...similar implementation for Asteroid.CollideWith(...)

This works, but if you end up with lots of different SpaceShip types then you are in for a hard time. If your group of asteroids is fairly static, you can use a Visitor-approach to accommodate lots of different spaceships. First we'll define an IAsteroid interface to represent the fairly stable group of asteroids, and an IAsteroidTarget as a Visitor, to represent anything that can collide with our stable group of asteroids:

//Element that accepts a visit, in Visitor pattern parlance
public interface IAsteroid {
  string CollideWith(IAsteroidTarget target);
}
//Visitor, in Visitor pattern parlance
public interface IAsteroidTarget {
  String CollideWith(Asteroid asteroid);
  String CollideWith(ExplodingAsteroid asteroid);
}

As our spaceships can "visit" the asteroid types, let's implement those next:

public class SpaceShip : IAsteroidTarget {
  public string CollideWith(Asteroid asteroid) {
    return "Asteroid hit a SpaceShip";
  }
  public string CollideWith(ExplodingAsteroid asteroid) {
    return "ExplodingAsteroid hit a SpaceShip";
  }
}
public class GiantSpaceShip : IAsteroidTarget {
  public string CollideWith(Asteroid asteroid) {
    return "Asteroid hit a GiantSpaceShip";
  }
  public string CollideWith(ExplodingAsteroid asteroid) {
    return "ExplodingAsteroid hit a GiantSpaceShip";
  }
}

Now comes the double-dispatchy emulation part. Let's make our asteroids accept visits from our IAsteroidTarget objects.

public class Asteroid : IAsteroid {
  public string CollideWith(IAsteroidTarget target) {
    return target.CollideWith(this); // <-- The double dispatchy part
  }
}
//Same implementation for ExplodingAsteroid : IAsteroid ...

The emphasised part of the code above delegates the way each target will be hit to the target itself. A slightly modified version of our original test will now pass:

[Test]
public void TestDoubleDispatchWorkAround2() {
  IAsteroidTarget ship = new SpaceShip();
  IAsteroidTarget giantShip = new GiantSpaceShip();
  IAsteroid asteroid = new Asteroid();
  IAsteroid explodingAsteroid = new ExplodingAsteroid();
  Assert.That(asteroid.CollideWith(ship), Is.EqualTo("Asteroid hit a SpaceShip"));
  Assert.That(explodingAsteroid.CollideWith(ship), Is.EqualTo("ExplodingAsteroid hit a SpaceShip"));
  Assert.That(explodingAsteroid.CollideWith(giantShip), Is.EqualTo("ExplodingAsteroid hit a GiantSpaceShip"));
}

Obviously there are disadvantages to this pattern. If you need to add more asteroid types things are going to be painful. (There are also much better ways of implementing this particular example of returning strings, but that is just due to its contrived nature. For a realistic example see Jeremy's post.) On the other hand, the process of adding targets is now trivial, even non-spaceship ones:

public class Earth : IAsteroidTarget {
  public string CollideWith(Asteroid asteroid) {
    return "Asteroid hit Earth";
  }
  public string CollideWith(ExplodingAsteroid asteroid) {
    return "ExplodingAsteroid hit Earth, causing the extinction of the dinosaurs";
  }
}

As an aside, this single dispatching behaviour of C# explains the cause of the generic overloading behaviour I mentioned before.

Finally, Derrick Coetzee has a good explanation of technical aspects of dispatching in C# with regards to the Visitor pattern.