Lately I’ve been toying around with Amazon’s cloud platform in .Net using the Amazon Web Services SDK (AWSSDK). Also along for the ride has been Ninject, which is a pretty awesome dependency injection framework. So if I want to have a class have a constructor dependency from an AWSSDK client class, that has to be wired up the same way your regular non-Amazon classes are, in a NinjectModule.

Fortunately, there are interfaces for all the client classes in AWSSDK, albeit with an unusual naming structure. The class for calling the Simple Notification Service is called AmazonSimpleNotificationServiceClient, but it’s corresponding interface is AmazonSimpleNotificationService. Note the loss of ‘Client’ on the end, and that it doesn’t begin with a capital I which is the typical norm for C# interfaces. Anyways, that won’t prevent you from using them in Ninject. The problem is that there are 20, count ‘em, 20 of these client classes. You could manually write all 20 in individual calls to Bind<T> but where’s the fun in that?

This module will load them based on their aforementioned naming convention.

	
public class AwsModule : NinjectModule
{
public override void Load()
{
var awsAssembly = typeof(AWSClientFactory).Assembly;

var amazonClientTypes = from t in awsAssembly.GetExportedTypes()
where t.IsClass && t.IsAbstract == false
&& t.IsPublic && t.Name.EndsWith("Client")
select t;

foreach (var clientType in amazonClientTypes)
{
string clientTypeName = clientType.Name;
int clientIndex = clientTypeName.LastIndexOf("Client");
string expectedInterfaceName = clientTypeName.Remove(clientIndex, 6);

Type interfaceType = (from clInterface in clientType.GetInterfaces()
where clInterface.Name == expectedInterfaceName
select clInterface).FirstOrDefault();

if (interfaceType != null)
Bind(interfaceType).To(clientType);
}
}
}


Note that this results in binds that end up resolving to their default constructors, not any of the overloads that take credentials or config objects. As is, the above code will use credentials from your app.config/web.config file by searching for AWSAccessKey and AWSSecretKey in your appSettings section. Which I’m fine with. I could have this or another module bind AWSCredentials to anything that derives from it, like BasicAWSCredentials. And similarly for ClientConfig if that’s your bag.

Recently I took another look at MongoDb, the document database that’s been around for quite a while. Now there’s a (really good) official C# driver. Coupled with third party LINQ support and some pretty damn good documentation, and I don’t see much reason to use NoRm or any other the other homegrown MongoDb .Net drivers.

One thing that stuck out to me was that there’s no implicit convention using the mapping capabilities to set the collection name for a given class type. Which, if you’re using generic repositories and you only have a System.Type, leaves you with the only option of hardcoding them (bad) or basing them off of the type’s Name or FullName (less bad). I wasn’t thrilled with either option so I wrote some extension methods to make them definable in the same manor as your class maps if you’re using BsonClassMap. Check it:

    public static class BsonClassMapExtensions
{
private static ConcurrentDictionary<Type, string> _cache = new ConcurrentDictionary<Type, string>();

public static string GetCollectionName(this BsonClassMap classMap)
{
string result = null;

if (_cache.TryGetValue(classMap.ClassType, out result))
return result;
else
return classMap.ClassType.Name;
}

public static void SetCollectionName(this BsonClassMap classMap, string collectionName)
{
if (string.IsNullOrEmpty(collectionName))
throw new InvalidOperationException("Collection name must be valid string.");

_cache[classMap.ClassType] = collectionName;
}
}
Now I can specify collection names as so:
            if (BsonClassMap.IsClassMapRegistered(typeof(Blog)) == false)
{
BsonClassMap.RegisterClassMap<Blog>(cm =>
{
cm.AutoMap();
cm.MapIdProperty(x => x.Id);
cm.SetCollectionName("Blogs");
}
);
}

And in my Mongo infrastructure/unit of work/repository implementation I can use

BsonClassMap.LookupClassMap(typeof(Blog)).GetCollectionName();

when necessary and it just works. Nice.

Getting Started With Node.js

Friday, September 2, 2011

 

Recently I’ve been playing around with Node.js, the new hotness that is event-based server side JavaScript. It’s been a bit challenging figuring out how to get it going on Windows since Windows support has only just recently been added. So here’s what I did to get all set up writing Node.js apps on Windows. This is more of a brain dump than anything because I have a tendency to get enamored with the new shiny thing and then ignore it for months until I come back to it having forgot all the details on the environment I had set up.

1 – Download the latest Node.js Windows executable from the most recent post on the Node.js blog. I put mine in c:\node

2 – Download and install Python 2.7.2 It has to be 2.x, this is a prerequisite for the next step.

3 – Download ryppi.py from it’s github repository and shove it in the same directory where you put node.exe. This is a python script that emulates npm, the node package manager, which does NOT support Windows, even under cygwin.

4 – Use ryppi.py in place of npm. In blog posts, where you see npm install <packagename>, execute ryppi.py install <packagename> in a command prompt where your node.exe is.

5 – Save the hello world web server sample as helloworld.js in your node directory and run node.exe helloworld.js from a command line.

I should mention that prior to doing all this I tried building node from source and executing it under cygwin which is detailed over on github. This is painful and error prone and I would recommend avoiding unless you really want to for some reason.

Helpful / Interesting link dump:

- Nodester.com is a node.js cloud hosting. Literally run a few command line utilities and your node app is running on a subdomain on nodester.com. I haven’t tried it out yet but it looks impressive.

- Nodecasts.org is a site for screencasts about node. Only two so far though.

- Expressjs.com seems to be the dominant web framework for node.js.

- Express-Resource is a module for express I’ve been playing around with that adds simplified RESTful routing over express.

Note: This is a re-post from my previous blog. I had mentioned this in an old StackOverflow question and decided to re-post it. Yes, I know the width of this blog is not conducive to big chunks of code. I’ll fix it sometime.

Of all the controls in the Asp.Net WebForms family I think I like the ObjectDataSource the most. It's a shiny beacon of hope in a framework otherwise bogged down by the perils of ViewState, heavy and un-testable infrastructure classes, and much to be desired in terms of abstractions. I know everyone else is all about the MVC angle bracket soup these days but for those (stuck or by choice) in WebForms land, ODS is fantastic. What it allows you to do, in short, is to make often awkward data-binding your bitch. Let's see how.

The essence of all data source controls is allowing you, the developer, to short-circuit traditional architectural techniques like layering and get to having working CRUD in a very just-let-me-get-this-done-and-go-home-what-do-you-mean-unit-testing fashion. SqlDataSource goes direct to a database, XmlDataSource goes to xml, and so on. ObjectDataSource is the only one that lets you break out of the 2-tier forms-over-data model that Microsoft likes to push. But what about LinqDataSource? Well, ODS works by binding to methods on a specified class in your code. Which, since it's your code, allows you much more freedom than any other the others, including the LinqDataSource. Want to provide a specific instance of the binding class to be consumed by the ODS at runtime by your DI container of choice? Want to invoke custom business logic or validation during the CRUD binding-calls? Want to use constructor injection and make your binding class actually, you know, testable? Want to actually put code in a place other than a web form's code-behind? Want to leverage server-side paging in Linq to Sql to only fetch and display the data you're concerned with showing? Want to pipe in some custom data from the http cache? All doable with ODS, the others not so much.

For a class to serve as a binding source for an ObjectDataSource, it needs:

  1. One or more methods to return stuff to bind against. Business objects, a DataTable, whatever. These methods can optionally have
    • Two integer parameters for paging (defaulting to 'maximumRows' and 'startRowIndex') indicating a subset of data to be returned
    • A string parameter for sorting, provided in the form of ColumnName DIRECTION such as ProductName ASC or UnitPrice DESC
  2. A public constructor. Unless you subscribe to the ObjectDataSource's ObjectCreating event in order to provide a custom instance before the binding calls are executed.
  3. A public method that returns the total number of rows not including the fetched-page size. This is only necessary if your ODS has EnablePaging set to true.
  4. Some attributes on the class or methods that do nothing but tell Visual Studio HEY! SHOW ME AS BINDABLE. Technically these are optional.

Which, in the case of Northwind might look like:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Northwind.Model;

namespace Northwind.DataBinding
{
[DataObject(true)]
public class ProductQuerySource : IDisposable
{
private NorthwindDataContext _dataContext;
private bool _disposeContextWhenDone = false;
private int _count = 0;

public ProductQuerySource(NorthwindDataContext dataContext)
{
if (dataContext == null)
throw new ArgumentNullException("dataContext");

_dataContext = dataContext;
}

public ProductQuerySource()
: this(new NorthwindDataContext())
{
_disposeContextWhenDone = true;
}

[DataObjectMethod(DataObjectMethodType.Select)]
public IList<Product> FetchAll(int startAt, int pageSize)
{
_count = _dataContext.Products.Count();

var query = _dataContext.Products.Skip(startAt).Take(pageSize).ToList();

return query;
}

[DataObjectMethod(DataObjectMethodType.Select)]
public IList<Product> FetchAll(int startAt, int pageSize, string sortExpression)
{
_count = _dataContext.Products.Count();

IQueryable<Product> products = _dataContext.Products;

if (!string.IsNullOrEmpty(sortExpression))
products = _dataContext.Products.OrderBy(sortExpression);

return products.Skip(startAt).Take(pageSize).ToList();
}

public int GetCount()
{
return _count;
}

public void Dispose()
{
if (_disposeContextWhenDone)
_dataContext.Dispose();
}
}
}

With our ObjectDataSource markup resembling

<asp:ObjectDataSource ID="odsNorthwindProducts" runat="server" 
OldValuesParameterFormatString="original_{0}"
SelectMethod="FetchAll" TypeName="Northwind.DataBinding.ProductQuerySource"
EnablePaging="true"
MaximumRowsParameterName="pageSize"
StartRowIndexParameterName="startAt"
SelectCountMethod="GetCount" SortParameterName="sortExpression">
</asp:ObjectDataSource>

Link that sucker to a GridView with AllowPaging and AllowSorting both set to true and you'll get a grid displaying Products in which only the products currently being rendered are even returned from the database. Click on a column header to sort? Current paged fetched and sorted in database. Fantastic. Note that standard parameter-binding applies here as well, Fetch() could easily have a categoryid parameter which might limit the results to all Products in that category. Since its all just methods on a class, our binding class can be tested using whatever the your testing strategy of choice happens to be.


Oh, but what about that pesky sorting? We can't sort a linq query by a string, can we? Well, yeah, normally that would be the case, but not to fear, because but by taking a bit of code based on this post by Pradeep Mishra (which has alot of typos in the code there, beware) we'll be able to dynamically use those string sort expressions to invoke Linq's OrderBy and OrderByDescending methods. Which, in the case of Linq to Sql, will result in the respective ORDER BY clauses being added to the query once it is executed against the database.

using System;
using System.Linq.Expressions;

namespace System.Linq
{
public static class LinqExtensions
{
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class
{
if (string.IsNullOrEmpty(sortExpression))
return source; // nothing to sort on

var entityType = typeof(TEntity);
string ascSortMethodName = "OrderBy";
string descSortMethodName = "OrderByDescending";
string[] sortExpressionParts = sortExpression.Split(' ');
string sortProperty = sortExpressionParts[0];
string sortMethod = ascSortMethodName;

if (sortExpressionParts.Length > 1 && sortExpressionParts[1] == "DESC")
sortMethod = descSortMethodName;

var property = entityType.GetProperty(sortProperty);
var parameter = Expression.Parameter(entityType, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);

MethodCallExpression resultExp = Expression.Call(
typeof(Queryable),
sortMethod,
new Type[] { entityType, property.PropertyType },
source.Expression,
Expression.Quote(orderByExp));

return source.Provider.CreateQuery<TEntity>(resultExp);
}
}
}

So having that in place means we can have SortParameterName="sortDirection" in our ODS markup as well as the sortDirection string parameter on the binding method. Hello, server-side paging and sorting.


I should note that this sorting and paging isn’t unique to Linq To Sql- it applies to anything queryable by Linq. It's just that leveraging this approach with Linq To Sql yields for a more elegant sorting and paging solution when working with a database than some other the other switch-based or (god forbid) stored-procedure based approaches.

Loving to Win / Hating to lose

Thursday, June 30, 2011

Recently I was playing around with the new Asp.Net MVC3 bits, specifically around getting a working endpoint for getting push notifications from the Amazon Simple Notification Service (SNS). I spent most of the time fighting with IIS 7.5 just trying to get something other than a directory listing to show up. Of course it turned out to be some obscure setting that had to be flipped that had nothing to do with MVC3. With deployment stories like that, it’s no wonder folks are leaving the .Net platform for others. A playful Sunday morning of coding turned sour because IIS won’t play nice.

It actually reminds of the recent NBA finals. Wait, here me out. I’m not a big pro basketball fan but I catch some sports radio here and there and I heard something that kind of stuck with me. The discussion was about Lebron James and how he had been struggling to close out games late in the fourth quarters when he is so talented and has so much talent around him. Then someone, a caller or one of the host pundits said something to this effect: Lebron loves to win. Kobe and Dirk and Durant and others hate to lose.

That concept shouldn’t be that foreign to anyone doing the whole agile thing. It’s built around the idea of success through failure. Fail early, adjust, and get better. Rinse, repeat.Have a continuous integration build that makes you smile when it runs without errors and 100% tests passing, but you don’t immediately drop everything and fix it when tests fail or someone checks in some broken code? You’re loving to win, but tolerant of losing.

Back to Microsoft. It seems like DevDiv is turning the corner on hating to lose. Most non-Microsofties would consider early versions of Entity Framework to be failures, even early versions of MVC, while promising, didn’t hit the spot for a lot of people.Now we’ve got EF Code-First, a more mature MVC, and Nuget, all big wins coming out of DevDiv. Then we’ve got the product teams which I assume are not part of DevDiv. The SharePoint teams and the TFS teams, even in 2010 are publishing APIs that are chock full of sealed classes, static methods, with no interfaces leaving any developer actually interested in unit testing against said API left out to dry. It’s really telling that MVC has projects adding bells and whistles, while TFS has projects that only exist to wrap the untestable API itself. One’s winning, one’s losing.

Do you hate to lose or love to win? What about your team? Your organization/company?

Regarding the Real World

Thursday, June 2, 2011
I see this alot, lifer developers in big IT referencing what they do being contrary to 'the real world' where things like ajax, care towards user experience, advanced testing techniques, etc are considered commonplace. If I was a manager this would be a fireable offense.

Just because you work in a big 'enterprise' on brownfield apps that haven't been touched since Net 1.1 days doesn't mean you can't improve it. Just because your organization is dysfunctional doesn't mean you cant make improvements in the code you see and write everyday. Using the excuse that you're not in the real world using bleeding edge stuff as a reason to basic techniques like unit testing and SOLID, patterns, etc, is just that: an excuse. And guess what? The so called 'real world' projects have problems too, but they're sucking it up and solving them. What are you doing?

You are not your code

Wednesday, May 11, 2011

Rob tweeted:

This thread is a fucking embarrassment for all .NET developers (read toward the end) groups.google.com/group/subsonic…

And it is. Poor guy is having some performance problems with SubSonic compared to Entity Framework when loading 1 million rows in his application. Then he goes to say he’d rather quit than use inline SQL to get better performance.

Pretend you’re in that situation. Your building some analytic fat client application that shoves fancy dashboards in the faces of middle managers so they can maybe make better business decisions. Would they care that you used a bit of inline SQL to gain some performance? Would they care that you use an ORM? I’m going to go out on a limb and say that they wouldn’t. They want their dashboards and whiz bang analytics to work and work well and perform well. You know, the stuff that you’re actually supposed to be delivering.

Im all for ORMs and clean code and patterns and SOLID and software craftsmanship but like most things, they’re best in moderation. There are exceptions to every piece of guidance/pattern/scenario out there.

An unwillingness to accept a given solution does not mean that the solution does not exist. Solve the right problems. You are not your code.

top