Friday, November 13, 2009

The Simplest Possible Ninject log4net Binding

I’ve been using Ninject more and more. I also use log4net for logging. But how to do I get my log4net peanut butter into my Ninject chocolate? Like this:

Bind<ILog>().ToMethod(x => LogManager.GetLogger(x.Request.ParentContext.Plan.Type)); 

As far as I can tell, this is the simplest possible way to get Ninject to build an ILog object for dependency injection. NOTE! This is only valid for dependency injection! If you just call:


kernel.Get<ILog>();

You will be less than satisfied with the results… However, this works brilliantly:


public class Notifier : INotifier
{
private readonly ILog _log;

public Notifier(ILog log)
{
_log = log;
}
}

No wrappers, static classes or helper objects! If I ever meet Nate Kohari, I’m going to give him a big ol' hug. I may even tear up a little bit…

Wednesday, April 22, 2009

Installing Contribute Publishing Services on Windows Server 2008

We use Adobe Contribute to edit/manage our web site at work. We’re also steadily moving to Windows Server 2008. I was thus a bit disappointed to see that when I tried to install CPS on Windows Server 2008, it just sat there – trying to install, but in fact doing nothing at all. Being a) stubborn and b) probably stupid (let’s face it, Contribute is dead), I was able to bring it up by copying an existing installation from Windows Server 2003 and then registering the services appropriately. Here’s what I did (your paths and server names will vary). In this example, WEBSTAGE is the old Windows Server 2003 box and WEBSTAGE08 is the new Windows Server 2008 box.

  1. Copied C:\Program Files\Macromedia\Contribute Publishing Services from WEBSTAGE to WEBSTAGE08.
  2. From the Command Prompt, created the CPS service (note space after “binPath=” – important and annoying to miss)
    sc.exe create CPS binPath= ”C:\Program Files\Macromedia\Contribute Publishing Services\jrun4\bin\jrunsvc.exe”
  3. Exported HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\Macromedia Contribute Publishing Server from WEBSTAGE to CPS1.reg.
  4. Exported HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CPS from WEBSTAGE to CPS2.reg.
  5. Edited CPS2.reg and removed the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CPS\Security and HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CPS\Enum sections.
  6. Imported CPS1.reg and CPS2.reg on WEBSTAGE08.
  7. Started the Macromedia Contribute Publishing Server service on WEBSTAGE08.
  8. Added firewall exception to allow access to all ports opened by C:\Program Files\Macromedia\Contribute Publishing Services\jrun4\bin\jrun.exe.
  9. Opened https://webstage08:8900/contribute/admin/server.cfm.
  10. Logged in with old admin password and changed to new admin password.
  11. Switched to Website Settings panel and deleted webstage website.
  12. Launched Contribute CS3, created a new connection to WEBSTAGE08 and added https://webstage08:8900/contribute as the publishing server.

That’s it. Can’t believe it worked, really.

Monday, April 13, 2009

A DSL for IoC Configuration

Just kind of thinking out loud here... Seems like a fantastic use for an M grammar! Hmm...

// Include file from assembly resource
include res://CWS.SoCHelp.NHibernate/Basic.config

// Include file from C: drive
include file:///C:/Users/sherwooda/Documents/Visual%20Studio%202008/Projects/CWS.SoCHelp.Tests/Extended.config

// Include file relative to executable
include file://~/Fluent.config

// Declare aliases for namespaces and assemblies
alias SoCHelp (CWS.SoCHelp, CWS.SoCHelp);
alias NHibernate (CWS.SoCHelp, CWS.SoCHelp.NHibernate);
alias Tests (CWS.SoCHelp.Tests, CWS.SoCHelp.Tests);

// Basic configuration, map service to type, default to "singleton" with no name
SoCHelp:IUnitOfWorkFactory -> NHibernate:NHibernateUnitOfWorkFactory;

// Map open generic with transient instance and no name
SoCHelp:IRepository`1 -> NHibernate:NHibernateRepository`1 transient;

// Don't use aliases, map exact type specified
"CWS.SoCHelp.IUnitOfWorkFactory, CWS.SoCHelp" ->
"CWS.SoCHelp.NHibernate.NHibernateUnitOfWorkFactory, CWS.SoCHelp.NHibernate" singleton;

// Specify an identifier for a service
$Command = Tests:ICommand -> Tests:Command singleton;

// Map specialized generic
$UserRepo = SoCHelp:IRepository`1[[Tests:User]] -> Tests:UserRepository transient;

// Parameters specified
$RedBookFinanceRetriever = Tests:IRetriever -> Tests:HttpRetriever singleton
{
url = "http://www.megacorp.com/financials/redbook.csv";
timeout = 3000;
}

$BlueBookFinanceRetriever = Tests:IRetriever -> Tests:HttpRetriever singleton
{
url = "http://www.megacorp.com/financials/bluebook.csv";
timeout = 3000;
}

// Refer a dependency to a previously created component
$ExternalFinancialProcessor = Tests:IProcessor -> Tests:AuditProcessor
{
retriever = $BlueBookFinanceRetriever;
}

$InternalFinancialProcessor = Tests:IProcessor -> Tests:AuditProcessor
{
retriever = $RedBookFinanceRetriever;
}

// Declare a bunch of commands
$JumpRope = Tests:ICommand -> Tests:JumpRope;
$PickUpSticks = Tests:ICommand -> Tests:PickUpSticks;
$Honk = Tests:ICommand -> Tests:Honk;

// Pass an array of components to a dependency
Tests:IProcessor -> Tests:CommandProcessor
{
commands = [$JumpRope, $PickUpSticks, $Honk];
}


Wednesday, January 28, 2009

Kelvin's First Playlist

Someone was VERY upset this morning. We believe he may have been pleading for Child Protective Services based on the volume of his cries.. I put together a little playlist for him and we danced and danced and he LOVED IT! He calmed right down! Went from 60 to 0 in like 1.4 seconds. It was amazing! Daddy is very tired though. That was a lot of dancing and singing for someone as out of shape as I am..

Here's the playlist:

I Love Beans - Cartoon Planet BBQ
I'm On Standby - Grandaddy
Secret Monorail - Parker Paul
I'm A Believer - The Monkees
Day O - Harry Belafonte
Particle Man - They Might Be Giants
Swinging On A Star - Bing Crosby
Jump In The Line - Harry Bellafonte
If I Wasn't Shy - They Might Be Giants
Stand - R.E.M.
Across The Universe - Fiona Apple (Pleasantville Soundtrack)
You Ruined Everything - Jonathan Coulton
Pork And Beans - Weezer
A Knife And A Fork - Information Society
With A Little Help From My Friends - The Beatles
A Fable With No Moral - Quasi
Stroller Town - Jonathan Coulton
Foux Du Fafa - Flight Of The Conchords
Manta Ray - Nan Vernon
Mr. Blue Sky - Electric Light Orchestra
Put A Lid On It - Squirrel Nut Zippers
Fearless - Pink Floyd

Tuesday, January 20, 2009

Understanding The Scale of Kelvin

My son, Kelvin was born 1/16/2009 at 09:14PST, measuring 7.5lbs and 20.5 inches. Some people may have trouble visualizing the scale of our new bambino, so I've provided this handy guide...

1G iPod Touch, 8GB



XBox 360 Wireless Controller




1G Playstation Portable




80GB 2.5" 5400RPM Serial ATA Hard Disk Drive




WALL-E Blu-Ray Disc



Now if you'll excuse me, I need to go analyze some poop for color and consistency...

Sunday, January 4, 2009

How I Spent My Winter Vacation : Two weeks with the Azure Services Platform

I've had the past two weeks off of work and spent the time really digging into the Azure Services Platform from Microsoft. I'll spare everyone the descriptions and assume you know how to use Google if you're unfamiliar with it. My goal, I thought, was quite simple. I would create a small web application that would serve a small number of customers (dozens, perhaps). I decided on a pet licensing application, as the data model would be fairly simple. I looked at some of the paperwork from our cat adoption, poked around a few county sites for pet licensing and came up with a simple domain model. Great! Now to build an Azure application around it!

Getting Started
The first step was to sign up for the CTP. Read my blog post about that here. It was initially a bit confusing. Mostly due to the massive number of things Microsoft unleashed on the world all at once. While waiting for my magic tokens, I prepped my machine by installing the Azure SDK, Visual Studio Tools for Azure and Azure Management Tools. Lucky for me, a good Samaritan from Microsoft was listening to my tweets and helped me get my tokens right away. It sounds like if you didn't go to the 2008 PDC, you're going to be waiting awhile for access to Azure's Hosted Services (where you run ASP.NET applications). I ended up with two storage accounts and one hosted service, plus access to SQL Data Services, Service Bus, Workflow Service and Access Control Services. Sweet!

Hello Cloud!
Like all software developers, I started off by writing "Hello World". First, I got it working on my machine using the Development Fabric, then I created a new Hosted Service and stepped my way through the prompts to deploy my application. It was relatively straight forward, but I wasn't always sure if I was doing the right thing. There are a lot of status codes like "Initializing..." and "Allocating...", but nothing to indicate how long I should twiddle my thumbs for. Speaking of thumbs, here's a rule of thumb for all things Azure: be patient. Just walk away - go get a cup of tea or harass some people in the marketing department. By the time you get back, there will probably be green lights waiting for you and you can proceed. What you have to do is usually fairly obvious, how long it will take, is not. Anyway, after some navel gazing, I had "Hello World" published to the cloud. Woohoo!

Running ASP.NET MVC on Azure
I'm a glutton for punishment. As such, I decided to cram as many new technologies into my skull as possible. I had read a few blog posts about people running ASP.NET MVC on Azure, so I thought I would give it a shot. Aaron Lerch has a fantastic piece up on how to get it up and running on the Development Fabric. Just follow the instructions! One thing to note, this ate one of my two Storage Accounts. ASP.NET MVC needs cloud-based providers for membership, role management, profiles and sessions. The samples included with the Azure SDK include everything you need and Aaron walks you through the process of setting up your application to use the appropriate providers. You should also read through the Cloudy in Seattle posts (here and here) on ASP.NET MVC and check out Maarten Balliauw's CarTrackr.

All of those posts are great and they'll definitely help you get ASP.NET MVC up and running on your local machine, but they all kind of gloss over how to deploy your application as a Hosted Service. As luck would have it, there's an excellent MSDN article that covers this very topic. By following the instructions there, I was able get ASP.NET MVC app hosted in the cloud with minimal difficulty.

Inversion of Control and Dependency Injection on Azure
One of the great things about ASP.NET MVC is that they've really been listening to the development community and respect the work the ALT.NET/xDD folks have been doing. Fundamental to xDD is the concept of inversion of control and dependency injection for the creation and management of objects. Again, I won't go into the details (your Google finger isn't broken is it?), but there are a myriad of options available: Castle Windsor, StructureMap, Unity, Ninject, Autofac... The list goes on and on. Lots of people like writing IoC containers because they're fun and functional! So my next task was to figure out which IoC container I could use with Azure and ASP.NET MVC. My needs for an IoC container were as follows: run under medium trust, cannot rely on attributes for configuration, support registration of open-ended generics and support constructor argument injection at configuration. Here's the run down:

Castle Windsor
- My preferred IoC container, but it won't run under medium trust. Out!

StructureMap
- My second favorite IoC container. Runs under medium trust locally, but not under Azure. Submitted bug report to Jeremy Miller. Reading through the StructureMap user's group, it looks like he's going to try to fix that early this year.

Ninject
- I didn't really monkey around with Ninject much. The sample code I saw was riddled with [Inject] attributes, which kinda turned me off. Apologies to @nkohari if I dismissed it too early.

Autofac
- Works great in medium trust under Azure, easy to configure, but doesn't support registering arguments for constructor injection at configuration time. You have to specify them when you resolve the service.

Unity
- No problems at all! Worked great in medium trust on Azure, easy to configure, supports everything I need! I gotta say I'm really impressed by how far Unity has come in such a short time.

Persistence, Perpetually
This is where things started to go awry. I'm an NHibernate guy. It's ridiculously easy for me to create a domain model, write up some mappings to the database and bam - persistence is done. The Entity Framework lets me do essentially the same thing, but I prefer the way NHibernate works with POCOs. I also like LINQ - a LOT. I mean seriously, I could kiss Anders Hejlsberg square on the lips. You can perhaps imagine my disappointment when I looked at the sample data access methods for Azure Table Services and SQL Data Services and saw pages and pages of infrastructure code to store even the simplest entity. Here's what I want to do:
_container.Resolve<IRepository<Contact>>().Save(new Contact { Id = Guid.NewGuid(), Name = "Fred" });
Bam! Entity in database. StorageClient (for Azure Table Services) offers something like this functionality, although you have to derive your domain objects from TableStorageEntity. Unfortunately, Azure Table Services is fairly limited at the moment - tables are non-relational and there are no joins. There's also this warning in the documentation: "The StorageClient sample library is not optimized for performance and is not intended to be used for building robust services, but only as an example of a working client library." Ouch.

At this point, SQL Data Services was starting to look a little more desirable. When I import a service reference to the SQL Data Service into a .NET project, I'm basically staring at the repository pattern. That coupled with the fact that it supports intra-container joins made me jump ship to SQL Data Services. Plus, this is about learning! I wanted to touch as much of the platform as possible. Out of the box, the only thing missing from SDS is LINQ. So after poking around for awhile and not finding anything of consequence about LINQ to SDS, I set about implementing the repository pattern and with IQueryable support. I worked on it for about two days and was probably about 80% done when I found this: SSDS REST Library. I was more than a little upset. It was buried in the noise of Google's search results and I didn't happen upon it until I was looking for some help implementing IQueryable. Sigh.

It was around this time that I thought to myself, "Self, you might be missing the forest for the trees here. What about Astoria?" Astoria is/was the code name for ADO.NET Data Services - a way of exposing access to data stores via RESTful web services. It even supports LINQ right out of the box (well, mostly)! Unfortunately, Microsoft hasn't issued a CTP for ADO.NET Data Services over SQL Data Services yet. In fact, it seems like there are some "issues" aligning the two (three, if you count Azure Table Services) offerings.

At this point, I'm a bit frustrated with the persistence picture for Azure. Yes, it's very service-oriented. There are REST APIs through the wazoo - but I don't want to spend my time building and dissecting magic strings for queries and entities. I want to type repo.Save(entity) or repo.Delete(entity) and be done with it. I will say that both Azure Table Services and SQL Data Services both seem to have nailed the data set extension problem. It's VERY easy for a multi-tenant application to extend the schema per-client. Kudos to Microsoft for that!

Ironically, the biggest problem with persistence in Azure applications is that there are so many choices. Microsoft seems to be attacking the problem from multiple directions and I'm unsure which battalion I should join up with.

Future Directions
Unfortunately, I've run out of time and I wasn't able to finish my application, but I have learned a ton about Azure and I'm fairly comfortable moving around the platform now. However, there is still so much more to learn. I didn't even scratch the surface of queues, workflow, the service bus or live ID. These are all areas I intend to investigate - but at a much slower pace. I also BARELY touched on some of the major architectural issues with building Azure applications. I had a great conversation with David Chou, Joseph Healy, Shan McArthur, Roger Jennings and others on multi-tenant Azure applications over on the Windows Azure MSDN Forums.
In the end, I'm probably going to switch to Azure Table Services and StorageClient because I can work with it offline using the Development Storage. Any future work I do with Azure will probably be done on the MAX (Portland's mass transit system), so this is more out of necessity than preference.

Overall, I gotta say I had a BLAST working with Azure! Yes, there were a few frustrating moments and plenty of rough edges, but when I look at what the blue badges are putting together, I see the future. These guys are really thinking hard about what it's going to take to build gigantic, accessible, scalable applications. This isn't just "let me host your CPU for you" - it's truly an internet-scale operating system in the making. Right now I think the two best players on the field are Microsoft and Amazon. It may seem odd that I've left Google off that list, but they don't even rate compared to what Microsoft and Amazon are offering right now. There are a handful of others out there: RightScale, Yahoo, VMWare, etc - but I think Azure is the platform to beat.


Tuesday, December 23, 2008

How To Sign Up for Windows Azure

There are three services to sign up for: Windows Azure, .NET Services and SQL Data Services. You sign-up for all of these services here: http://go.microsoft.com/fwlink/?LinkID=129453

You will NOT receive your tokens immediately. It make take awhile. Also, there are different tokens for different services and they may arrive at different times. This can be confusing, but basically you just need to be patient. You will need TWO invitation tokens to receive access to all three services.

Windows Azure - provides computation services, hosting for ASP.NET applications and access to Azure Storage (blob, queue & table). Requires invitation token with the form XXXXX-XXXXX-XXXXX-XXXXX-XXXXX, where 'X' is [0-9A-F]. Access via the following URL: http://lx.azure.microsoft.com/fs

.NET Services & SQL Data Services - provides access to Service Bus, Access Control Service, Workflow Service and SQL Data Services. Requires invitation token with the form: XXX-XXXX-XXXX, where 'X' is [0-9A-Z]. Access via the following URL: http://portal.ex.azure.microsoft.com/

Please note, Azure Storage != SQL Data Services. Azure Storage provides rudimentary database support via the table storage. SQL Data Services provides more conventional database concepts.