Welcome

Please contact me (Phil Haack) at here with any errors, problems, and/or questions.

To learn more about the application, check out the Subtext Project Website.

Powered By:

Syndication

Blog Stats

Bloggers (posts, last update)

Latest Posts

Sorting a List

I came across a different requirement today, I need to sort some objects in a certain order that wasn't alphabetical or numerical.  I looked towards SQL for a few minutes and found zilch that could help me with ORDER BY shinanigans.  I could have done multiple queries and then merged the results, but that would be pretty messy.  I ended up using Sort(), which I used before, but never to do anything more than a simple sort.

Consider that I have the following Employee objects with a Name and Position property like:

Joe, President

Frank, Vice President

Bob, Developer

that need to be sorted in that order.  Obviously sorting alphabetically wouldn't work so what to do?

Sort to the rescue!

Employees.Sort(CompareEmployeesByPositionInCompany);

with CompareEmployeesByPositionInCompany looking like:

private static int CompareEmployeesByPositionInCompany(Employee x, Employee y) {
            int xSortValue = GetSortValue(x.PositionInCompany);
            int ySortValue = GetSortValue(y.PositionInCompany);
            const int before = -1;
            const int same = 0;
            const int after = 1;

            if (xSortValue == ySortValue) {
               return same;
            }
            if (xSortValue < ySortValue) {
               return before;
            }
            return after;
         }

private static int GetSortValue(string value) {
            if (value == "President")  return 1;
            if (value == "Vice President") return 2;
            if (value == "Developer") return 3;

}

posted @ 8/12/2008 2:08 PM by Willie

Update Table with column and default value

When updating a table with a new column first I'd do something like:

alter table myTable add isGreat bit null

then fill that column with a value like so:

update myTable set isGreat = 0 where IsConfirmed IS NULL

Turns out there's a shortcut to that sucker:

alter table myTable add isGreat bit null default 0 with values;

posted @ 8/7/2008 12:11 PM by Willie

Earthquake? I'm coding biatch

I had just gotten done talking to the boss about getting Resharper 4 and doing and upgrade to VS 2008.  I walked back to my office and was in the doorway when the "medium" one hit.  Having never been in a earthquake larger than one that shakes me about a tad it was weird seeing the floor shake around.

A train was going by right outside the office, so at first I thought that it was just the train, but then a huge bump came and I was wondering if the ceiling was going to come down.  I was going back to code, but then thought, "well I'm supposed to stay under a door or something and here I am already."

I called out to the other people in the office to see if everything was alright.  My co-worker though didn't seem phased in the slightest.  In fact, he looked up, then went back to coding.  Now that's some intense concentration!

posted @ 7/31/2008 1:44 PM by Willie

NCover is alive again?

Looks like 3 peeps brought NCover back from the grave of sorts.  While the product never died, it did go commercial which essentially left us poor peoplies with no coverage tool.   Glad to see it resurface in the open source area again.

posted @ 7/30/2008 11:19 AM by Willie

Server Client and back again

Wouldn't it be totally possible to have an application have both a server and client piece?  Both would contain a list of each connected IP addresses to the each of the connected machines to a central server machine.  This would allow more of a push technology to populate a sceen, and if a server went down it probably wouldn't be a big deal because then a client app could just take over server duties anyway.

posted @ 7/28/2008 3:06 PM by Willie

Why would you have a custom server to pass data from a database?

I have a client-server application that is going from the client to the server.  From there the server is getting data back from SQL Server and then through the serialization process sending it back to the client.  Why not just go directly to the SQL Server?  What could be the benefit.  The SQL Server and Server module are both hosted in the same area so I don't think it's security.  Maybe it's just proprietary stuff... but I'm not sure.

posted @ 7/28/2008 3:01 PM by Willie

Hey buddy, wanna make 0 dollars?

As I get older I realize that my instinct are pretty much dead on about 90% of the time.  When warning flags shoot up, I really, really, reeealy need to start paying attention to that inner voice that is telling me, "Somethin fishy going on here."

I get a call on Sunday at 7PM.  A person who was a friend of a friend tells me that he needs a "master page layout" done, but that it has to be done by the next day.  There's 400 bucks if I'm interested.  The catch is, that it has to be done by the next morning.  I figure, 400 bucks for just a master page, why the f not?

I killed my Sunday fun short and got home around 10:30PM.  Usually, this is when I'd make some preperations for bed, and for the Monday instead.  I steeled myself for the long haul before the upcoming week by saying...it's for 400 bucks.  Should be pretty straight forward.  Got it done right around 1AM.

Not bad right?  You don't get paid too many side jobs at a rate of 200 an hour very often.  I don't hear much, but then get a call from the design company.  They say the client wants some small changes.  Then they say that I should talk directly to the client, could I meet at 9AM?  I say no to that, but agree to something after work.

I talk with the designer, he wants me to ok more work, and a red flag goes up.  Why on earth would he be wanting ME to ok work for him?  I'm not paying him...  Kind of weird but I move on.  Then I have to talk with the flash guy.  Then I finally talk with the client.  So far I've invested about 3 hours total now with all the talking involved.  I talk with the client and he's talking about javascript rollovers, dynamic ajaxy (his words) effects, and more graphics that he can change on the fly.

I make some more changes, and then get some more stuff off to this guy.  He's just not happy with anything.  He wants me to change the appearance of the page now, more javascript stuff, etc.  So far I'm 6 hours in, and not happy.  I tell him that he needs to be talking to the company that's giving me this job (when the hell did I become the PM for this thing).

He then goes to that company and essentially fires them.  I'm stressed out, wondering wtf just happened, and wondering if I'm going to see anything for all this trouble.  My Monday was pretty bad with me being so tired, and I'm still adjusting my sleep schedule 5 days later.  I finally get a hold of the project leader.

She says that she'd pay me the 200 bucks I was promised as I had done a lot of work and wasn't going to cheat me on that.  Wait...200 bucks, what happened to 400?  She also said that she didn't want to lose the client because they were a 100,000/year client.  And you're paying me 200 bucks out of that to do all this work?  I've just spent a Sunday working on this crap and now I'm now to $20/hour with all the time I've spent on this.  She then says that I will need to go through the friend of a friend to get the money.  Great, I'm now expecting $0/hour.

Lesson learned, when you feel just a tinge of "wtf is going on" just back away, turn around, and run like hell.

posted @ 7/18/2008 12:17 PM by Willie

Testing Homework

http://www.ayende.com/Blog/archive/2008/05/16/Rhino-Mocks--Arrange-Act-Assert-Syntax.aspx http://haacked.com/archive/2007/12/09/writing-unit-tests-for-controller-actions.aspx

posted @ 7/10/2008 7:30 PM by Willie

A disadvantage with _memberVariable or m_variable

In the past I used to prefix my member variables with a _ to denote to myself that it was a member variable elsewhere in my code.  For more global variables I'd do a __ or double underscore.  Eventually, I gave up this practice as I'm always trying to sacrifice keystrokes without hampering readability and didn't really see the need anymore to keep it in there.  My IDE (VS2k5 or 2k8 now paired with Resharper) would bluntly tell me with it's Intellesense (or code completion) that the variable didn't exist within the scope, so I'd go figure out what the heck was up. Within my current codebase they are practicing the _memberName, and no real problems, but a distinct disadvantage in my mind cropped up over working in the past day.

It came when we were trying to set a member variable within the scope of the class to a certain value. 

_blah = true;

Straight forward enough, the value should have been true, and all was right in the world.  Problem is, on the UI side, the _blah = true didn't make anything happen.  The Blah button never changed it's state.  Upon inspection it turned out the _blah was being set within by a property:

public bool Blah{
   set {
      if (_blah!= value) {
         _blah = value;
         BlahChanged();
      }
   }

Code aside, the fact is, the setter was actually firing off an event to the UI to let it know that things had been updated.  Now if my _blah would have been blah instead, I would have seen the blah and Blah next to each other in my code completion list.  With the prefix underscore, the initial _ filtered out the Blah from my list of variables and it required inspection that interrupted the code though flow to see wtf was going on.  In my book, that's a negative thing.

posted @ 7/9/2008 9:06 AM by Willie

Problems with Attached Database in Vista

I believe the problem started because I had Visual Studio on the machine before I installed the Management Studio and it's software.  I initially uninstalled the original Sql Server Express then reinstalled everything.  Before, connecting to it from a web app or application I could get in fine, but now was running into "Generating user instances in SQL Server is disabled. Use sp_configure 'user instances enabled' to generate user instances."  Not cool.

What I initially did was to open up my master and msdb databases and run the command on each, along with a second "reconfigure" command after it.  Then I restarted the server's service.  A new error emerged: "Failed to generate user instance of SQL Server due to a failure in starting the process for the user instance.  The connection will be closed."

This thread helped a lot as I did eventually need to remove some files  but under Vista there is no C:\Documents and Settings\<your user account name>\Local Settings\Application Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS.  In fact if you click on "Document and Settings" if you have the "show system files" selected then you will get an access denied message.  Turned out that these shortcuts are "junctures" and will give you this wierd error instead of redirecting you like you'd think they would.

I read through this article that went over just that and was able to then point to C:\Users\<User Name>\AppData\Local\Microsoft\Microsoft SQL Server Data instead of the XP equivalent of C:\Documents and Settings\<User Name>\Local Settings\Application Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS.

After removing those files, and then trying to reconnect, the master, msdb, and others were recreated and all was well in the world again.

posted @ 6/9/2008 11:12 AM by Willie

Poor Man's Shards in NHibernate

Another loosely coupled post on Going to Production with MonoRail.

One thing I haven't stressed in recent posts is the absolute necessity to thoroughly test and understand the implications of your modifications when you start pushing a framework outside of the box.  In my post on Advanced Dependency Injection with Castle Windsor I lightly touched on the lifestyle implications of my patch to the code.  The same warning covers today's post when we start jimmy jacking with a custom connection provider in NHibernate.

If you've been following along you know that for various reasons we host multiple clients on a single instance of our B2B web application.  For other various reasons we like to keep the data for each client segregated into separate databases.  We use NHibernate for persistence ignorance so that seemed to be the logical place to start when attempting to segregate client data.  When I was doing my research it became apparent that at a high level I was trying to implement a horizontally partitioned database.  In my case, partitioned by client.  Hibernate supports horizontal database partitioning through ShardsDario Quintana is in the process of porting Shards to NHibernate, but I don't believe it is quite ripe yet.  Shards appears to address all of the nuances and edge cases that would reveal themselves when attempting to logically split data.  My needs were much cruder and I was willing to sacrifice a fully functional implementation (see first paragraph above though).  

Each client hosted in our application has their own configuration file.  Within this file is a database connection string that points to the database for the particular client.  As long as the database structure of each database is identical, NHibernate is cool with that.  What I ended up implementing is a custom IConnectionProvider that would load the current client's configuration, read the connection string, and create a connection using that, rather than the connection string that would normally be read from your hibernate.cfg.xml file.  The sample code gets the job done.

namespace My.Application
{
  public class ClientConfigurationConnectionProvider : DriverConnectionProvider
  {
    public override IDbConnection GetConnection()
    {
      string clientId = ClientIdProvider.Get();

      if (null == clientId)
      {
        return base.GetConnection();
      }

      ClientConfiguration clientConfiguration = ClientConfigurationManager.GetByClientId(clientId);
      string dbConnectionString = clientConfiguration.DbConnectionString;
      if (string.IsNullOrEmpty(dbConnectionString))
      {
        return base.GetConnection();
      }

      IDbConnection conn = Driver.CreateConnection();
      conn.ConnectionString = dbConnectionString;
      conn.Open();
      return conn;
    }
  }
}

Very straight forward.  By inheriting from the built in DriverConnectionProvider, most of the hard work is done for us.  To tell NHibernate to use our connection provider, a small change to the configuration file is required:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <!-- <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property> -->
    <property name="connection.provider">My.Application.ClientConfigurationConnectionProvider, My.Application</property>
    <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string">Server=(local);Database=MyApplication;Trusted_Connection=True;</property>
    <property name="show_sql">true</property>
    <mapping assembly="My.Application" />
  </session-factory>
</hibernate-configuration>

Remember what I said though, depending on your database structure, and the features of NHibernate you choose to take advantage of, bad and unexpected things could happen with this implementation, so do your testing.

posted @ 6/8/2008 4:35 PM by Bill Pierce

Runtime Dynamic Actions in MonoRail with Windsor

Another loosely coupled post on Going to Production with MonoRail.

The ability to customize every aspect of an application Lego style is great, but there will always be client needs that are absolutely off the wall.  Not a customization of an existing component, but something so specific and unique to the client's domain that it cannot be encapsulated into something reusable.  My mind struggled with the paradox, how do I architect the ability to insert non-reusable functionality in a reusable way?  Mike Nichols put me on the path to my solution.

Dynamic Actions are a feature of MonoRail that allow you to decouple an action from a controller.  This sounds pretty simple but when you read through the documentation and the many ways that developers are putting them into practice, Dynamic Actions reveal their true power.  The first part of my solution: completely custom functionality is simply implemented by a class that implements IDynamicAction.  Each piece of custom functionality corresponds to a dynamic action.  The next question is how do I expose this functionality to the Client?  How do I ensure that this functionality is only exposed to the Client that paid for it?

I haven't yet posted about how we manage configuration for each client, but essentially we have an INI file (cringe! gasp! moan!) for each client hosted on a particular server.  A sample section of the INI file for the Contoso client would look like so:

[Actions]
DoWork=ContosoDoWorkAction
DoWork2=ContosoDoWork2Action

The key (DoWork) represents the name of the action, the value (ContosoDoWorkAction) is the name of a class that implements IDynamicAction and the logic for the custom functionality required by the client.  Actions are loaded into the child container for the Client during application startup.  Now we need a controller that we can attach these actions to at runtime.  This is achieved using the code sample below:

namespace My.Application
{
public class CustomController : Controller
{
public CustomController(IKernel kernel)
{
ClientConfiguration clientConfig = ClientConfigurationManager.GetCurrent();

NameValueCollection actions = clientConfig.Actions;

foreach (string actionName in actions.AllKeys)
{
string actionTypeName = actions[actionName];
Type actionType = Utility.GetImplType(actionTypeName);
DynamicActions[actionName] = (IDynamicAction)kernel.Resolve(actionType);
}
}
}
}

So simple it should be criminal.  With the configuration sample above and the CustomController implementation, we now have valid URLs of:

https://contoso.myb2bapplication.com/custom/DoWork.rails

https://contoso.myb2bapplication.com/custom/DoWork2.rails

At the same time, by the nature of our child container configuration magic, the following URLs would be invalid:

https://fabrikam.myb2bapplication.com/custom/DoWork.rails

https://fabrikam.myb2bapplication.com/custom/DoWork2.rails

This is because the actions are only available to the client for which they were configured.  By the same token I can disable an action by commenting out the line in the configuration file.

Who's your daddy paradox?

posted @ 6/7/2008 2:40 PM by Bill Pierce

Advanced Dependency Injection with Castle Windsor

Another loosely coupled post on Going to Production with MonoRail.

Many moons ago I wrote a post about dynamically resolving a component from the Castle container based on runtime parameters.  There was some discussion about the limitations of the approach (the biggest is that all components that require customization or components that have dependencies that require customization must be Transient) but overall it accomplished my goals at the time.  To summarize, my implementation allowed you to load multiple components that implement the same service (say an IOrderValidator) and also allowed you to provided a predicate that would be invoked when your code resolved an IOrderValidator to allow you to choose which specific implementation to return.  The idea was that you could have multiple clients hosted on a single instance of your application, each requiring their own order validation logic.  Using a runtime parameter (like the host header) your provided predicate would resolve the IOrderValidator associated with the particular client's requirements.  This implementation worked for some time but had a few limitations, namely all components for all clients had to be loaded into the same container.  This ended up being a tad unruly to manage.  There were also some limitations on the order in which components were loaded into the container, which was problematic when auto configuring the container via code or something like Binsor.

I set out for a better solution that addressed my new requirements and ran into the related issue of scoped containers that had been proposed on the Castle mailing lists.  Scoped containers have a slightly different use case and requirements but overlapped some with the approach I ultimately settled upon.  My container contains over thirty (30) components that make up the core functionality of the application.  Some of these components have dependencies on other components and all of this management, injection, and resolution is handled nicely and elegantly by the container.  Lets say for a particular client I need to customize one of the these components.  But the component in question has dependencies on three other components, whose functionality I do not need to customize.  I need a way to add my customized component to the container, but still resolve its dependencies from the core set of components.  The answer to my problem came in the form of Child Containers.

A child container is just like your standard container only that it has an associated parent.  When you try to resolve a component from a child container, it looks at its own components to fulfil dependencies and if it doesn't find it, it asks the parent container if it can fulfil the dependency.  This sounds like just the solution I needed.  I can load all of my core components into the parent container, then load any custom components into a child container.  One glaring flaw though.  Lets say I have component A that has a dependency on component B.  I have a core implementation of both components in my parent container.  I have a custom implementation of component B in my child container.  I attempt to resolve component A from the child container.  It is not present so it is retrieved from the parent container.  When resolving the dependency of component B, the parent uses the core implementation, not the custom implementation in the child container.  I considered this a bug in the dependency resolution code and you can read about the ensuing discussion on the Castle mailing list.  This issue was also reported by Rinat Adbullin a few months back and prompted him to choose another container implementation.  I submitted a patch for my implementation but as far as I know it has not been applied.  I've heard Hammett say that child containers are the devil (my words, not his) I believe because they can introduce difficult to diagnose bugs and make dependency resolution more complicated.  For my problem they have provided an elegant solution.

To bring this implementation into MonoRail was simply a matter of crafting a custom HttpApplication that implements IContainerAccessor, and returning the appropriate child container based on the host header of the current request.  I have the base container that contains all of the core components.  I create a child container with the base as its parent for each client and load the appropriate components.  MonoRail can be configured to use Windsor to resolve all of its internal components (including your controllers).  MonoRail calls IContainerAccessor.Container to obtain the container to use for its resolution.  By providing the appropriate child container to this call, I can ensure that any custom components for the particular client are used in place of the core components.  By using the dependency resolution patch discussed above, I ensure that any core component dependencies are properly resolved against any existing customized components in the child container (code sample below).

To sweeten the deal, child containers are configured using a simple text file that can be modified at runtime to turn individual custom components on or off on a per client basis, without restarting the application.  More on that in my future post on managing configuration.

namespace My.Application
{
  public class CustomHttpApplication : HttpApplication, IContainerAccessor
  {
    private static IWindsorContainer _baseContainer;

    private static readonly Hashtable _configToContainer = new Hashtable();

    protected virtual void Application_Start(object sender, EventArgs e)
    {
      _baseContainer = new CustomContainer();
    }

    public IWindsorContainer Container
    {
      get { return GetContainer(); }
    }

    protected virtual IWindsorContainer GetContainer()
    {
      string clientId = ClientIdProvider.Get();

      if (string.IsNullOrEmpty(clientId))
      {
        return _baseContainer;
      }

      ClientConfiguration clientConfig = ClientConfigurationManager.GetByClientId(clientId);

      IWindsorContainer clientContainer = null;

      if (!_configToContainer.ContainsKey(clientConfig.Path))
      {
        clientContainer = new CustomContainer(clientConfig, clientId, _baseContainer);
        _configToContainer.Add(clientConfig.Path, clientContainer);
      }
      else
      {
        clientContainer = (IWindsorContainer)_configToContainer[clientConfig.Path];
      }

      return clientContainer;
    }
  }
}

posted @ 6/6/2008 2:15 PM by Bill Pierce

Going to Production with MonoRail

We went to production with our B2B e-commerce product going on three months ago.  I've waited this long to write anything about it because I wanted to include in my documentation the process we used to address bugs we found after we went to the field as well as all of the interesting nooks and crannies of the architecture, what worked, what didn't, what I will do again, what I will be changing through careful refactoring, etc.  Over the next few weeks look for posts covering in some detail the topics outlined here.

Setting the Stage

This is a small application written by myself and one other dev over the course of three months.  This is not a COTS product nor is it written for a single client.  Our application provides a hosted set of core "out of the box" functionality that can facility B2B e-commerce as is, but all of our customers require some amount of customization.  When I said small, I meant small.  We average six (6) requests per second during business hours and spike to about forty (40) requests per second during peak times (moving the mouse on the server causes more CPU utilization than than the app itself :) The core application is only forty-three (43) models, six (6) controllers, forty-two (42) actions (including overloads), nineteen (19) views, and twenty-seven (27) services.  We integrate with five (5) third parties for things like credit card authorization and capture, real time shipping quotes, inventory availability, customer profile management, and order fulfillment.  We use a private build of  MonoRail RC3 with Windsor integration and Helen Keller's view engine of choice.  We use NHibernate 2 wrapped with Rhino Commons for persistence and log4net for all our logging needs.  This was a legacy application that has been in production for approximately four (4) years that originated as a classic ASP application, was ported to ASP.Net 2.0 Web Forms, then was refactored to a home grown ASP.Net 2.0 MVP framework, and is now in its current incarnation.

High Level Overview

I will be talking in volumes about the ability to customize nearly every aspect of our small application.  The reason is because all of our customers need the ability to receive an order from an end user, perform some sort of validation on the order information, then feed that order into their order fulfillment system.  The problem is that every customer has a slightly different take on end user, validation, and fulfillment system :)  Rather than write separate products for each customer or make a branch of the code for each customer we sign, our goal was to provide a core application that can be kept current, with new core features added as time goes on, and still allow any level of customization a specific customer requires.  This could be anything from re-arranging user interface elements on one or more screens, to making email address an optional field, to authorizing a credit card, but not capturing it, to feeding an order into SAP or into a legacy AS/400 order system via custom web services.  Some customizations become configuration options in the next release of the core product.  Others are so far out there they they will always remain customizations.  We also have the rare customer that happily uses the core product as is.  This model allows us to provide a tiered customization path: configuration changes can be made by operations monkey, view customizations can by made by any html monkey, and service customizations can be made by any code monkey (that's me).  So rather than giving our customer the brush off of "we will look at incorporating that in our next version", they flash us the cash and we do the deed, without affecting or breaking the core product or any other hosted customers.

The Highlights

Here are the topics I plan to touch on in no particular order.  Some will be brief others might span a few posts.  As I write the posts I will come back here and update the links and I might add other topics as I think of them.

  • Managing Configuration - Me: "Check out this new feature in v5", Marketing: "That's configurable right?"
  • Managing Customization - Marketing: "Customer wants to sell stuff without displaying prices", Me: "Ha ha, good one.  No...you're serious?...seriously?...are you kidding me?...are your f***king kidding me!"
  • Post Production - Patching, hot fixing, and tracking down bugs
  • NHibernate Tricks - Poor Man's Shards
  • Windsor Tricks - My Golden Swiss Army Knife
  • Layout Tricks - Handling Popup Windows, Sidebars, and Error Notification
  • jQuery Tricks - How do I love thee? Let me count the ways.
  • Brail Tricks - I have an Orange Belt in Quack Fu

posted @ 5/28/2008 12:04 PM by Bill Pierce

Populating a Hierarchical Table with Lineage Data

This works if you have a few things already in place, which I did.  You table must have

Id,

ParentId, (Points to the parent AKA adjacency hierarchy)

and Depth (which says how deep the element is.  I only had 3 levels so lineage works well in this case).

Set the root element's lineage to be the same as the Id.

Then run this till you get to your max depth, increasing the depth number each time.

UPDATE <Table_name>
SET Lineage = (SELECT Lineage FROM <Table_name> WHERE <Table_name>.ParentId = Id) + ',' + Cast(Id as varchar)
WHERE Depth = 1

There could very possibly be other ways to do this, but this seemed the easiest with what I had.

posted @ 5/14/2008 9:50 PM by Willie

Pretty Funny, Cause it's True.

posted @ 5/6/2008 8:43 PM by Willie

What kind of job do you want?

I was recently laid off, and this question keep coming up from recruiters.  It all seems like a stream of bullshit and I play along.  I mean, seriously, is the job I really want actually out there?  Somehow I highly doubt it, but I still smile and nod and just hope for the best.

Is there a job that I can work from home if I want to.  Putting in hours when I want, like early and the morning and then late at night?  I'm not sure why this 8-5PM work schedule is forced upon developers.  I do my best work early in the morning and then again late at night.  Don't you want my best?

Is there a job out there that will reward me for doing above and beyond what the original specs were for a project, well ahead of a deadline and way under budget?  Would I be recognized at that job for thinking outside of the box and coming up with a solution that no one else thought of?

Would I be able to take a vacation when I wanted, maybe a personal day near a weekend that would allow me to spend some time with my family?  Will my co-workers be "Ok" with me not knowing everything there is to know.  Will they help me to learn what I should know?  Will they help me grow to fulfill my potential?

Will it be exciting and change the world?  Will it at least help people in some tangible way?  Will I be able to notice the change my job has put forth?  Can I look back and say, "Yeah, I created that.  Isn't that sweet?  Look how everyone is using it.  I did that!"

That's the kind of job I want.  The one that doesn't feel like a job, just another hobby that I do my best at.

posted @ 5/6/2008 1:26 PM by Willie

Something I didn't know about Math.Round

The method seems easy enough.  It rounds a number right?

Math.Round(1.25, 1) = 1.3 right?

Nope.  It will = 1.2

From the documentation:

The number nearest d with a precision equal to decimals. If d is halfway
between two numbers, one of which is even and the other odd, then the even
number is returned. If the precision of d is less than decimals, then d is
returned unchanged.

How to fix?

Math.Round(1.25, 1, MidpointRounding.AwayFromZero) = 1.3

I'd think this would be the default way, but for some weird reason it isn't.  I also wonder if this has changed as I don't remember having this issue with the 2.0 framework.

posted @ 4/29/2008 9:35 AM by Willie

Which came first, the chicken or the database?

When designing applications that deal with databases I have always started with designing out a schema through the actual database.  This entailed writing table creation scripts, setting up relationships within the database and all that jazz.  For development purposes, in an effort to remain agile, I'd also code up some INSERT statements to push data into a newly created database so that I could test everything.

Bill Pierce, has of course been telling me about NHibernate and Castle's ActiveRecord for quite some time now, but I always felt that it was backwards.  You create the database first, then you create a data layer.  Right?  I mean pretty much every code generation tool that I've used in the past follows this model.  And since this model has worked for me for quite awhile, why change?

It turns out that NH and AR in my eyes make "being agile" way easier.  Instead of managing three (or more) separate tools like a database management tool, code generation tool, etc you just manage your code.  It's actually so simple, that at first I didn't believe it.  Yes, getting a project up and working is a bit painful as these are open source projects so a lot of times the documentation for something that looks like it would really help is just plain missing.  Once you do get rolling though, it's extremely simple to go from the whiteboard directly to code, and not worry about anything else.

The problem is though, it's really hard to convince someone without them actually exploring and doing it themselves.  Case in point: myself.  I've been looking at this stuff for a year or so, and finally after really working with it I believe that it is a better way to code an application's data layer from the ground up.

These two lines of code make it all happen:

ActiveRecordStarter.DropSchema();
ActiveRecordStarter.CreateSchema();

This short bit of code recreates (makes me want to add a ActiveRecordStarter.RecreateSchema()) your database and allows you to enter new information.  Sure, the way I used to do it was to run a SQL script to do this for me, but now this just happens automatically. 

Why is this so powerful?  It makes it so that any change that I make in my data objects is made within my database with no hassles.  I LOVE the fact that you can use OO principles to add common fields to all tables.  SubSonic uses CreatedBy, ModifiedBy, CreatedOn, and ModifiedOn to show some change tracking.  To plop this into all tables I simply have my ModelBase:

[ActiveRecord]
public class ModelBase<T> : ActiveRecordBase<T>, IModelBase
{
    /// <summary>
    /// Will save the record with information about the creation and modification of it.
    /// </summary>
    /// <param name="userName"></param>
    public virtual void Save(string userName)
    {
        if (this.CreatedBy == null)
        {
            CreatedBy = userName;
            CreatedOn = DateTime.Now;
        }
        ModifiedBy = userName;
        ModifiedOn = DateTime.Now;

        base.Save();
    }

    [PrimaryKey]
    public int Id { get; set; }
    [Property(NotNull = true, Length = 255)]
    public string CreatedBy { get; set; }
    [Property(NotNull = false, Length = 255)]
    public string ModifiedBy { get; set; }
    [Property(NotNull = false)]
    public DateTime CreatedOn { get; set; }
    [Property(NotNull = true)]
    public DateTime? ModifiedOn { get; set; }
}

 

and I call it a day.  In fact, if any of those fields in the database needed to change, or another needed to be added, it would be so incredibly simple to change them that it would take a second thought.  In any code generation model, I'd have to bring up the database management tool, and start editing tables, or going through a lengthy script to make the necessary changes.  Having recently done a ton of that, I say yippee to the newfound way.

There are other benefits that I've found, but to me this was the biggest benefit to NH and AR that I've come across so far.  It also gives me pause to think that maybe I was coding up data layers backwards before because this just feels so natural.  I still believe that if you have an existing database, a code generation tool would probably make more sense if it can accomplish what you need.  I feel that things should only be done once, so if the database is already created, I don't want to rehash out xml files or AR classes to accommodate them.  If you are starting from the ground up though, this "way" sure is cool.

The one thing I really don't understand, and maybe it's out there, is why hasn't someone tried to combine the code generation with NH and AR.  I'm already thinking up some ideas on how SubSonic's generation tool could enhance AR classes.  I wonder if you could enter something into RecreateSchema that would call sonic.exe...

posted @ 4/22/2008 9:28 AM by Willie

Building my own MSBuild script Part 2

Now to compile my project.  For some reason there was really not to many "here's how you do it" examples out there, so I'll post mine.  Pretty simple, and maybe that's why there was a lack of simple tutorials to cover it.

 

<Target Name="Compile">
        <MSBuild Projects="Abpm.sln" Targets="Build" StopOnFirstFailure="false" ContinueOnError="false" Properties="Configuration=$(Configuration)">
            <Output TaskParameter="TargetOutputs" ItemName="BuildTargetOutputs"/>
        </MSBuild>
    </Target>

 

Other Targets="Build" attributes that I saw but didn't work for me were the Clean and Rebuild.  I'm guessing I'm missing an import someplace. 

posted @ 4/15/2008 9:19 AM by Willie

Learning myself some DI with a dash of IoC

I've been looking in dependency injection and inversion of control containers for awhile, but never really got into actually coding them out.  Sure they looked all shiny, separation of concerns, easy to test, blah blah.  It didn't really smack me in the head until recently when I had to change some code, of which I have 97% code coverage (thank you very much).  I added a simple method and changed a calculation.  Now writing some tests to make sure my ass is covered should be pretty easy right?  Nope.  In fact, it became a big pain in the butt as the dependencies on the object that I want to test become a perty long list.

I began to dig and again read a bunch of articles, and the one that is helping me the most right now is from the dotnetslackers site called Inversion of Control and Dependency Injection with Castle Windsor Container.  A series of 4 articles, of which I went through the first one.

Instead of just reading and saying, "Yeah, cool beans", and then forgetting everything until the next time I have a problem I decided to actually create the application mentioned in the article.  I hit a few snags that I'd like to highlight for anyone else going down the same path.

You need to add references to Castle.Core, Castle.MicroKernel, and Castle.Windsor to your sample project.  Go to the download section on the Castle project site to get those.  Might seem stupid, but I didn't know, thanks Bill.

The next thing that wasn't so obvious, was to create a app named WindsorSample.  This will help when copying the config or code files.  From there I actually created a super simple app, where I pasted the castle config into the app.config.  I also added a textbox for the address that I wanted to scrape the title from, a button to handle the event of getting the title, and a label to display the title.  The namespaces also gave me a moment of pause, so my modified code from the sample provided is below.

 

private void button1_Click(object sender, EventArgs e)
{
    Castle.Windsor.IWindsorContainer container = new Castle.Windsor.WindsorContainer(new Castle.Windsor.Configuration.Interpreters.XmlInterpreter());

    HtmlTitleRetriever retriever = container.Resolve<HtmlTitleRetriever>();

    label1.Text = retriever.GetTitle(new Uri(textBox1.Text));
}

 

image

posted @ 4/4/2008 10:21 AM by Willie

RFI Keeping Open Source Dependencies Up To Date

We just deployed the first phase of a new project that uses a large number of open source components including Castle (Windsor & MonoRail), NHibernate, and Rhino Commons to name the big players.  As with any project as much as I know about programming I learned even more when the rubber met the road.  Many right decisions were made, some wrong decisions were made, and the code has only been deployed for a month and I'm already making a long list of how I can do it better next time. 

One particular area that I want to get better at is staying current with dependencies.  Most OSS projects are constantly being improved and still remain stable.  Here is how my project began...I downloaded a debug build of Castle RC3, picked out the assemblies I needed, and added them to my /trunk/lib folder (What I look back on as my first mistake).  I built the latest trunk revision of Rhino Commons, and added those assemblies to my lib folder (at least I was consistent).  I then happily worked on my application, writing code, unit tests, a build script, life was good.  As we progressed in development there was a few things we needed to do in MonoRail that just didn't jive with MR conventions.  So, I synced to the RC3 branch, changed two lines of code, rebuilt, and updated my libs (second BIG mistake).  Life was good again, but then ran into a small snag with Rhino Commons.  Ok, I was able to tweak MR just a bit, so I can do the same with Rhino (see consistent, but I shoulda learned :).   Hmmm...the AI Sourcing machine has been busy and Rhino Commons has changed quite a bit since I grabbed the source last.  So I had to do some digging and diffing to find out what rev I had built from previously.  Finally I get back to the right rev (I right it down this time) make my changes, rebuild, and update my libs.  Coding progresses, but eventually I run into the same situation again, this time I actually commit a copy of the relevant (read only the projects that I need to tweak) code into our source repo (which isn't SVN to make things even more interesting) and begin to diligently comment explicitly the lines I change.  Just call me Sofa King Screwed :)

I'm a half way decent coder but I make dumb decisions sometimes.  I acknowledge that, and I want to get better.  At some point I will need to re-up my dependencies or be forever locked into an out dated version.  What I'm looking for is a better way.  What do you do with your OSS dependencies?  I've read posts where devs refer to a "private branch" which I presume to be a more organized approach to what I ended up doing.  Do you merge with the projects trunk?  How often do you merge with the projects trunk?  Are your dependencies built with your application or do you build them separately and only reference the assemblies?  Dan's post on How to Branch Properly got me thinking that may be the way to go.  Grab a trunk copy of the dependencies to be used, add them into my application's solution/build process, and merge with the trunk on a scheduled basis.  If appropriate the changes I make to my private branch can be refactored into patches to be submitted.  Is this an approach any of you have used?  Does it work?  Have you automated the trunk merge process?  We don't use SVN, but our source control solution is touted as king of merging, so I presume it would be fairly straightforward.  The other issue is when my dependencies depend on each other.  Oren makes it look easy.  This leads me to believe that the right approach is to stick with the build/reference as lib approach.  I'm willing to earn my paycheck, but if somebody already has a working solution, I'd love to hear about it.

posted @ 4/3/2008 9:44 AM by Bill Pierce

Building my own MSBuild script Part 1

"The OutputPath property is not set for this project" is the first error that I'm running into.  To solve it, I added a:

<OutputPath>.\Debug</OutputPath>

 

To my <PropertyGroup> collection.  It seems this value needs to be set, and it needs to correspond to what configuration you have setup ex: Debug/Release.

posted @ 3/27/2008 10:57 AM by Willie

Why is there both a user and login name?

image

Why is there both a user and login name?  Why do I seriously have to place this in both boxes?  Is there a good reason for this?  I could plop a different User name in there that I would think would only lead to confusion later on.  Weird.

posted @ 3/17/2008 3:48 PM by Willie

Upgrading Silverlight 1.1 Alpha to 2.0 Beta

http://msdn2.microsoft.com/en-us/library/cc189007(vs.95).aspx

No more managed downloader, replaced by Webclient. 

 

Some event names change. 

XamlReader is in System.Windows.Markup. 

Image.Source changed from string to ImageSource:

background.Source = new System.Windows.Media.Imaging.BitmapImage(new System.Uri("Levels/" + mapBackground.GetValue(Image.SourceProperty).ToString()));

BrowserHost changed to App.Current.Host.Content which wasn't in the above document.

posted @ 3/11/2008 9:05 AM by Willie

SQLite Manager for Firefox

What can't you do with Firefox?  https://addons.mozilla.org/en-US/firefox/addon/5817 brings you a SQLite Manager right in yer browser.  Neato.

posted @ 3/6/2008 4:09 PM by Willie

Is XAML forgetting CSS?

Looking through a little bit of XAML code today got me thinking after seeing a bunch of <TextBlock FontFamily ... FontSize ... Foreground ... Background /> it sure looks like the days of Web 1.0 where we had a lot of font-size, color, and font-family attributes.  We progressed though to use CSS later on, but now it looks like with Silverlight there's a big step backwards again?  Interesting...

posted @ 2/29/2008 2:29 PM by Willie

RIA The Next Generation - My thoughts on Flash, Silverlight, and JavaFX

Recently I started playing around with Silverlight to create a game.  A fun time was had by all (being just me) in creating it, and I learned a lot.  After sharing it with everyone I started looking into other rich Internet application technologies out there. 

The biggest one right now is coming from Adobe with their Flash/Flex/AIR technologies.  I used to create some things with Flash a long time ago and when I was getting more and more into .NET technologies Flex came out.  I immediately went back to Flex to see what I could do.  I was immediately stopped by the huge price tag and that was it.

The price tag is still there, and to someone who has already invested in other tool sets just can't justify getting that as well.  What it comes down to is what Microsoft is trying to do: Get designers and developers into the same tool sets.  While it sounds all peachy, the tools MS has out just seem strange to me.

Flash has one tool for everything.  You are able to code up some ActionScript in the same window you design a button.  Everyone can be on the same page pretty easily.  With MS's offering you have 3 tools: Expression Design, Blend, and then Visual Studio.  Now here's where I have the issue.  Design and Blend should be the same tool.  While doing things in Blend I kept trying to do things that I could do back in Flash 3 and 4.  Fact is, the design tools in the latest Blend just stink.  You can use Expression Design to do some things that should be available in Blend, but you have to convert everything to a path - like a stoke on some text.  Converting to a path sucks as well because there is no "Un-convert from path" once you've gone down that road.  This becomes really apparent when using text, but is an equal pain with shapes and other objects as well.

Once you've got things "just right" in Design you then have to go to Blend to configure your animations.  What a pain in the ass.  It's almost as if Microsoft is trying to create a new job position "design and code integrator" that is just not needed.  A designer should be able to do both the design and animations in one tool with no conversions.

The ease of use is also pretty staggering.  I wanted to make a cool visual button, and I downloaded the tutorial to do it.  After looking at the 1 of 48 pages (seriously) it would take to make a button I decided to go with an ugly square with some text.  That was easier!

Flash has got a ton of designers too, designers that for some weird reason like Macs.  Whatever their vices, that is their choice, and rightly so Flash can be designed out on a Mac.  For some strange reason Microsoft ripped out this functionality from Expression Design.  Big WTF on this one, as there goes like 75% of the designers.  Great...now I have to design stuff myself.  You can bet you'll see lots of cheesy looking apps with "I'm not a designer excuses" attached in the future on the Silverlight...greato potato.  So far I see a fat FAILURE next to the Microsoft's goal of getting the designers and developers on the same page with Silverlight.

To put further heat on Silverlight, Adobe just came out with AIR.  AIR allows you to have a Flash applet outside of the browser window, just like a regular OS application.  AIR is kinda a, "yeah it's cool, but after 30 minutes who cares", type of feature that allows you to run Flash apps outside of a browser, besides there's already ways to Interop with Flash through other languages already.  Tack in an Internet aware client and bingo bango same deal.  I remember looking at how to use Flash in a Windows app a looong time ago and realized after viewing a few top 100 videos from AOL that they could have accomplished the same years ago.  The thing is though, Flash has still got a ton of designers, and enough ActionScripters to develop kick ass apps to further the AIR phenomenon, so who knows.  AIR does suffer from UI slowness, which roughly means that when I click on a button, in applications I'm used to something happening immediately.  AIR makes my computer feel a tad slowish because it's grabbing crap off the net.

JavaFX is the last thing I took a look at.  So far JavaFX could be huge, as it has tons of developers that would love to roll right into a RIA and start coding.  The problem here is again designers, which I see Flash not losing for a loong time.  JavaFX is has a lot more of the Open Sourcey taste to it though so who knows what kind of designer that side of the fence can come up with.  Until that time, and until JavaFX can really come out with something tangible it's not really a threat and is already losing the web 3.0 battle.  With their OS'ness though they are able to run on Mac's (and Linux) equally well so that could be a head start there...

This battle is far from over and just beginning.  Right now, it's a "what you know...use" world as nothing out there is making me want to jump ship to another side.  The one thing I love though is that we're finally seeing ways that you can make applications that truly act, and look exactly the same across browsers and operating systems.  Very cool indeed.

posted @ 2/29/2008 10:57 AM by Willie

MadPegs a Silverlight game, in beta

I got the game into shape so that I could show it to other people besides my kids and wife.  The sound effects will probably change, but these made my kids laugh so whatever. 

Play the game

image

I took out the images of my family and put in images from the open source movie Elephant's Dream.  There's only really one level that I've done up, as the other levels were designed with a 640x480 resolution, something I later found didn't allow you to place that many pegs on the screen and made the levels really short.  If you do succeed in getting through the levels they'll just loop back.  So far, not the best reward system for a game, but I'm looking into how to store scores and all that fun stuff.

The timing of the game needs to speed up, but I was having some tunneling issues that I'll probably try to fix before doing that.  Graphics are also another thing that needs to be spiced up, but not a priority, maybe if someone else wants to help on that front?

posted @ 2/25/2008 10:57 AM by Willie

Getting a precise LinearVelocity with Farseer Physics

Update: I was not on the right track.  I used the formula S = So + vt + 1/2at^2 to come up with both Ax and Ay components like so:

float distance = (float)Math.Sqrt(Math.Pow(horizontalDistance,2) + Math.Pow(verticalDistance, 2));
const float pixelDistancePerSecond = 215;
float travelTime = distance / pixelDistancePerSecond;
float Ax = horizontalDistance / travelTime;
float Ay = (verticalDistance - 10 * (float)Math.Pow(travelTime, 2)) / travelTime;

 

I'm trying to make a object with mass 1 travel from a specific point to another point under a gravity of (0,20) 20 downwards. I have the radians angle from my starting point to my ending point, and have measured the horizontal and vertical distances between the two as well. To accomplish this task I'm thinking there has got to be a conversion ratio that I could use to send my object x amount of pixels. To illustrate, I believe I need to find the magic ratio:


float Ax = (float)(horizontalDistanceFromCenter * magicRatio) * (float)Math.Cos(radians);
float Ay = ((float)(verticalDistanceFromCenter * magicRatio) * (float)Math.Sin(radians)) + 20;
ball.BodyObject.LinearVelocity = new Vector2(Ax, Ay);


Am I on the right track?

posted @ 2/22/2008 4:28 PM by Willie

Getting Transforms from a TransformGroup in XAML

Each XAML object can have transforms applied to it.  Scale, Skew, Rotate, and Translate can all be applied to a XAML object by attaching them to a TransformGroup and then attaching that to the object.  You can also individually attach Transforms to the object as well.  The problem I found was trying to read value from within code.  For instance I had:

<Rectangle Width="50" Height="20" Fill="#FFFFFFFF" Stroke="#FF000000" Canvas.Left="161" Canvas.Top="331" RenderTransformOrigin="0.5,0.5">
    <Rectangle.RenderTransform>
        <TransformGroup>
            <ScaleTransform ScaleX="1" ScaleY="1"/>
            <SkewTransform AngleX="0" AngleY="0"/>
            <RotateTransform Angle="-8.727"/>
            <TranslateTransform X="0" Y="0"/>
        </TransformGroup>
    </Rectangle.RenderTransform>
</Rectangle>

Currently this is how Blend 2 Dec 07 Preview outputs a Rectangle that you drag to the screen, and then apply a rotation on it.  I wanted to grab the RotateTransform object and read it's Angle value for my game since I'm using it as a level designer.  Problem is, you don't have something like:

myRectangle.RenderTransform.Children

that you could grab as a Transform group, instead you actually grab the RenderTransform as a TransformGroup itself and go from there.  The resulting code:

((myRectangle.RenderTransform as TransformGroup).Children[2] as RotateTransform).Angle

Whew, glad we got that out of the way.

posted @ 2/21/2008 1:29 PM by Willie

Silverlight MadPegs Game

A week ago I was ramping down on a proof of concept http://www.gameplanhq.com/ and wanted my next project to be a learner - or something I hadn't done before.  I also wanted it to be fun.  I've been working on too many business types of applications...so thought about doing a game.  I thought of the XNA Game Studio stuff, but wanted to lean more towards something on the web, as it's my profession, and as such might possibly get more value to my learning if I went that way.

Microsoft is pushing out their Silverlight technology, and it just so happened that I got a book Introducing Microsoft Silverlight 1.0.  The book was ok, it was basically an introduction, but the biggest part of the book, for me, was the 1.1 Alpha portion.  Using compiled code to control the Silverlight application.  Cool, now we're talking.

Upon more investigation on the web, I happened across the Farseer Physics Engine and really started to feel like things were being put in place.  Andy Beaulieu had written up a Getting Started with Farseer Physics and Silverlight - geez, my life is getting easier by the minute!  Within this article, Andy had a gem of a class called SpriteBase.  By using this class I was able to get up some physical circles and squares bouncing about in minutes.  How freaking cool is this!

Now what game to make.  Peggle was a game that my wife was liking.  I did too, but I had thought in the past how I could make it cooler.  Well...MadPegs was now born!  Mwa ha ha ha haaa.

image

The key differences here are that the game is a continual loop, updating the animation, and state, of each element continuously.  One thing that I noticed early on, as I was trying to modify SpriteBase to include the translate and rotate elements, is that programmatically created elements do not perform as well as elements that are actually written out in the xaml files.  If that doesn't make sense... <MediaElement x:Name="Sound" /> is better than in code: MediaElement Sound = new MediaSound();.  I'm guessing this is due to the alpha state of Silverlight 1.1, and will be resolved in the future. 

The other fun tricks that I re-learned about was ATAN and vector arithmetic.  I'll make my math teachers proud by saying, I did use that after school.  In fact, more of the math stuff in the game was pretty easy, I'm sure the more complex the game, the more complex the math involved.

ATAN was necessary to figure out the angle between two points.  Specifically, the shooter (the circle with the square) points towards the mouse.  Vector arithmetic was necessary to the initial ball coming out of the shooter.  After that the ball bounces around on the pegs making them disappear, getting points, and eventually landing at the bottom.

For all of this interaction I used the observer pattern, another newish thing to me since I've been just dealing with a webpage and not individual components.  I could have used events for this, but felt that writing events for each object that was talking to the other was a bit harder than just having a one Update method on the observer.

The last portion that I've worked on is getting an easy to use level editor.  For this I just reused the Expression Blend software to create a UserControl that contains all the map elements.  When I create my level I loop through the various elements and recreate the level within my Page.xaml.  Now...I'm starting to rethink this method as sometimes the ball goes through a peg or doesn't bounce correctly due to the fact that I'm recreating each Peg programmatically. 

image

I'm also looking at sounds and music.  I've found a few creative commons liceansed material for sound and images, but nothing really for sound clips when the pegs are hit.  So far I've recorded a few sounds of myself making noises like "Oh", "Ee", "Ow", "Doh" and etc but the wife says they're annoying so might come up with something different.  I'll put a URL out for anyone that wants to try the game out when I get a few more things ironed out.

posted @ 2/20/2008 11:50 AM by Willie

Lazy Loading with nHibernate Under Medium Trust

Medium Trust is the Devil.  If you do not know what Medium Trust is in the context of ASP.Net, then I will leave you with one request and you can skip the rest of this post.  I entreat you to please mark all of your assemblies with AllowPartiallyTrustedCallers unless you have a compelling reason not to.  By adding this single attribute you remove the first of many hurdles that users of your software must contend with when running under Medium Trust.  If Medium Trust is such a pain, why would you ever subject your application to it?  Most third party hosting companies (GoDaddy, 1and1, WebHost4Life, etc.) lock down their servers to Medium Trust.  If you own a box or rent your own dedicated/virtual private server, then you don't have to deal with the pain that all of the other budget hosters are subjected to.

I am a big fan of nHibernate and am currently working on a little application in my free time that uses it.  It is a small time application and I don't have a lot of spare scratch so I started researching some shared hosting environments.  That is when I ran into Medium Trust and began investigating what that meant for nHibernate.  There are a lot of posts and forum entries out there on the topic so make sure and do your homework.  Mike Gavaghan has a nice chronicle on his Medium Trust adventure.  I compiled a list of what was needed to determine the feasibility of running nHibernate in Medium Trust.

  1. Add 'requirePermission="false"' to your nHibernate configuration section in your web.config file.  Ok, no big deal, nice and easy.
    <configSections>   
    <section name="hibernate-configuration" requirePermission="false" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
    </configSections>
  2. Disable the Reflection Optimizer.  The docs say you may see a performance boost during initialization but see a performance hit over the long term operation of your app.  Run your own tests to determine the impact.  Again a simple configuration change.
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <reflection-optimizer use="false" />
    <session-factory>
    ...
    </session-factory>
    </hibernate-configuration>
  3. Disable all lazy loading of entities.  Whoa!  Big deal!  No Way!  Can't do it!

nHibernate saves me a lot of coding and pain by abstracting my datastore and provides a sweet Criteria API.  It also lets me structure my object associations to transparently retrieve entities from my data store in an 'on demand' fashion.  That statement glosses over a lot of details that you really need to familiarize yourself with if you decide to start using nHibernate.  But suffice it to say I consider it a critical feature. 

Why can't I use lazy loading in Medium Trust?  Lazy loading requires the generation of 'proxy' classes that delay the retrieval of associated entities from the data store until they are actually accessed in code.  I tried to find a better explanation but the best I could come up with is a dated Server Side.net article.  The generation of proxy classes requires Reflection permissions that are not granted in a Medium Trust environment.

After all this research it looked like I wouldn't be able to use nHibernate the way I wanted to in a Medium Trust environment.  I cried for a while and my wife comforted me and said maybe I should try Linq to SQL which made me cry even more.  Eventually I settled down and started thinking some more.  nHibernate needs to make a proxy for my entity.  OK, I've come to terms with that.  My entities do not change during the execution of my app, so I would think that the proxies wouldn't change.  Is there a reason why the proxies need to be generated at run-time?  Why couldn't they be pre-generated and deployed with the app?  Hmm...I need to do some spelunking in the nHibernate sources.  What creates the proxies?  A ProxyFactory of course.  OK, I will need to make one of those.  How do I tell nHibernate to use my ProxyFactory?  Well, I need a ProxyFactoryFactory and a small configuration addition...let's escape from the dark inner workings of my mind and cut to the chase.

I labored for a few hours and came up with a free tool that will allow you to generate an assembly containing pre-generated proxies for the purpose of enabling lazy loading in a Medium Trust environment.  That's right, free.  Not free as in speech.  Free as in I did all of the hard work so you wouldn't have to.  This tool is creatively named NHibernate Proxy Generator (NPG.exe) and it should be a nice addition to your nHibernate tool chest (right next to NHibernate Query Generator).  The implementation is quite...ghetto...the reason is due to the fact that my programming skills are sick, not IL, and I failed weaving in Home Ec.  My immediate plans are some refactorings that remove some of the dependencies that were used out of expediency (Boo Compiler and ILMerge).

NPG is currently of a quality between Meware and Alpha.  I want to stress that it is still very raw but I have tested it with both nHibernate mappings and ActiveRecord entities.  The command line syntax is very basic and it integrates nicely as an AfterBuild target with MSBuild.  Here is what you need to get started.

  1. Download the binaries or sources.
  2. Follow steps one and two above.
  3. Build the assembly containing your nHibernate or ActiveRecord entities.
  4. Run from the command line, passing the name of the input assembly from step two, and the name you would like to use for your output assembly.
    NPG.exe /in:My.Entities.dll /out:My.Entities.Proxies.dll /lazy:+
  5. --or--   You could add something similar to the following in the project file for your entities project:
    <Target Name="AfterBuild" Inputs="$(OutputPath)$(AssemblyName).dll" Outputs="$(OutputPath)$(AssemblyName).Proxies.dll">
    <Exec Command="..\..\tools\NHibernate.Proxy.Generator\NPG.exe /in:$(OutputPath)$(AssemblyName).dll /out:$(OutputPath)$(AssemblyName).Proxies.dll /lazy:+" />
    </Target>
  6. Add the following to your nHibernate configuration:
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <reflection-optimizer use="false" />
    <session-factory>
    ...
    <property name="proxyfactory.factory_class">StaticProxyFactoryFactory, My.Entities.Proxies</property>
    ...
    </session-factory>
    </hibernate-configuration>

The tool should work with any nHibernate Trunk build at revision 3090 or better.  When you run into issues with the tool, have suggestions for improvement, or want to add functionality please let me know.

posted @ 2/17/2008 4:35 PM by Bill Pierce

Updated SVN Ignore List

bin obj Logs *.user *.suo Thumbs.db *.Publish.xml _ReSharper* *.resharper TempPE CVS Files* *backup* *ClientBin*

TADA!

posted @ 2/12/2008 4:14 PM by Willie

Question for Generic Specialists

This is not a quiz, I would genuinely like some help here.

Can some explain to me why this compiles:

IEnumerable<int> ints = new int[0];

And this compiles:

IList<int[]> ints = new List<int[]>();

But this does not compile:

IList<IEnumerable<int>> ints = new List<int[]>();

And subsequently this does not compile:

public void Generic_List_Of_GenericType()
{
  List<int[]> ints = new List<int[]>(); 
  MyMethod( ints ); 
}

public void MyMethod(IEnumerable<IEnumerable<int>> test)
{
}

It is not clear to me why the compiler can figure out the first two cases but not the latter two.

posted @ 2/12/2008 8:22 AM by Bill Pierce