Unknown's avatar

About harperj1029

Runner, hiker, javascript nerd

Javascript Memoization with underscore

If you’ve not discovered the handy use of Memoization, I encourage you to look into it and take advantage. 

My Use case

So, I was generating a large UI on the client using knockout.  I had pre-loaded some “lookup data” (imagine id/name pairs in memory) that I’d repeatedly look up as I built a grid of sorts.  So, imagine having to do that lookup hundreds, or thousands of times, for only a handful of unique ids – thus repeating the calls a LOT!  This is where memoization shines.

The awesome underscore library has a simple implementation to use.  Here’s a simple bin which demonstrates the usage (note I put my own hasher in there, as the default hasher only keys off the first parameter to your routine – which you’ll see, is the same in my case for all 4 calls).

jQuery.when – Sometimes it’s the little things

Yeah, so today, I’m pulling down boatloads of JSON in this application I’m working on (mainly lookup-data-ish-data), and obviously if I’m going to use some of that data to do lookups, I need to wait until they’re all downloaded.  So, instead of some cheese eventing hack, I took advantage of the the little gem known as jQuery.when

(fyi, sorry for the crappy code-formatting below.  some day, i hope to take 15 minutes to figure out why either Live Writer or this crappy “Code” plugin suck so bad).

So, once my little lookup playloads were down, I was able to use it, nice-and-clean.  So, here’s where I slam down 4 ajax calls:

var ajaxSmackDown= function () {
     var promises = [];
     promises.push(detailsUtility.ajax(first ajax call here);
     promises.push(detailsUtility.ajax(first ajax call here);     
     promises.push(detailsUtility.ajax(first ajax call here);     
// (call as many as you want here…) return promises;
};

and here, we wait *when* to do our other stuff until they’re all done:

var promises = ajaxSmackDown();
$.when.apply($, promises).then(function () {
     // Do what you needed to wait on here
, function (e) {
     global.exceptionHandler(e);
});

Generic Cache helper for your asp.net MVC project

Scenario

ok, so everyone caches crap in one way or another, right (in fact, how many times have you written one of these little cheeseball cachehelpers in your career by now?).   Well, this is probably my hundredth, but maybe someone will find this one helpful.  This simple cachehelper is designed to encapsulate cached global items as well as session-based items (encapsulating, thus allowing any technique to be used internally).  In this implementation, global caching uses simple static-caching techniques, while the session makes use of…well…the session.  Easy to change later as scenarios permit.

The API is meant to be simple, and to minimize forcing the developer to work with thread-locking crap too.  So, in the case of global cache items, the developer, checks to see if an item is cached, while providing a Func<T> setter to call if the item is *not* cached, thus removing the need for revealing locking and such.  The session based one just requires an object of type HttpContextBase.

Here it is:

    {
        T EnsureGlobalItem<T>(Type key, Func<object> setter);
        T EnsureSessionItem<T>(HttpContextBase context, 
               Type key, Func<object> setter);
        void InvalidateSessionItem(HttpContextBase context, Type key);
     }

In our case, we inject this into our consumers, which tend to be asp.net MVC controller

public class StandardCacheHelper : ICacheHelper
    {
        private static IDictionary<Type, object> _cache;
        private static object _lock = new object();

        static StandardCacheHelper()
        {
            _cache = new Dictionary<Type, object>();
        }

        public T EnsureGlobalItem<T>(Type key, Func<object> setter)
        {
            lock (_lock)
            {
                if (_cache.ContainsKey(key) == false)
                {
                    _cache.Add(key, setter());
                }
                return (T)_cache[key];
            }
        }           

        public T EnsureSessionItem<T>(HttpContextBase context, 
            Type key, Func<object> setter)
        {
            VerifyParam(context, "context");
            VerifyParam(key, "key");

            lock (context.Session.SyncRoot)
            {
                if (context.Session[key.FullName] == null)
                {
                    context.Session.Add(key.FullName, setter());
                }
                return (T)context.Session[key.FullName];
            }           
        }

        public void InvalidateSessionItem(HttpContextBase context, Type key)
        {
            VerifyParam(context, "context");
            VerifyParam(key, "key");

            context.Session.Remove(key.FullName);
        }

        private void VerifyParam(object param, string paramName)
        {
            if (param == null)
            {
                throw new ArgumentException(string.Format("{0} must not be null.", paramName));
            }
        }
    }

s via Ninject:

public class UtilityModule : NinjectModule
{
public override void Load()
{
this.Bind<ICacheHelper>().To<StandardCacheHelper>().InSingletonScope();
}
}

The base controller exposes the helper as such:

    public class BaseController:Controller
    {
        private ICacheHelper _cacheHelper = null;

        public BaseController(ICacheHelper cacheHelper)
        {
            this._cacheHelper = cacheHelper;
        }

        public ICacheHelper CacheHelper
        {
            get{return this._cacheHelper;}
        }
    }

And then finally, the consumption is clean and simple (and testable of course!):

public class Foo{
     public string Name{get;set;}
}

private IEnumerable<Foo> GetFoos()
{
     Func<object> setter = () =>
      {
           return this.myService.GetFoos();          
      };
      return this.CacheHelper.EnsureSessionItem<IEnumerable<Foo>>(
this.HttpContext, typeof(IEnumerable<Foo>), setter)
}

Enjoy.  I’m coding my face off these days (love it!), so I’ll be posting lots more.  I’ve got a bunch of handy custom knockout bindings, some nice clean javascript modules to use (using the javascript module pattern), extensions to Javascript and many more helpful things.

MVC is so refreshing

After spending so much time on SharePoint, it’s so refreshing to head back over to super productive (and incredibly enjoyable) frameworks like MVC.  We’re using MVC 4 at the new gig, and this is going to provide highly effective. 

The user community (made even easer with NuGet) for MVC is fantastic.  We’re using the typical approach (from bottom up) of an ORM (EF in this case) hidden behind a generic IRepository contract, business/service layer exposing behind simple contracts, base implementations to get us 80% there OOTB (and prevent redundancy of course), Ninject with it’s awesome IDependencyResolver goodness for MVC for Inversion of Control, and a nice clean Test story, taking advantage of MOQ.

Soooo refreshing!!

Look up the default web in IIS

Default as defined by port 80, no host headers and is running on the local machine:

private string GetDefaultWebPath()
        {
            string result = null;
            using (var de = new DirectoryEntry("IIS://Localhost/W3SVC"))
            {
                foreach (DirectoryEntry child in de.Children
                .Cast<DirectoryEntry>()
                .Where(d => d.SchemaClassName == "IIsWebServer" &&
                     d.Properties["ServerState"]
                     .Value.ToString() == "2" /* Started*/))
                {
                    var bindings = child.Properties
                        .Cast<PropertyValueCollection>()
                        .Where(i => i.PropertyName == "ServerBindings")
                        .ToList().Cast<PropertyValueCollection>();
                    if (bindings.Count() == 1 && bindings
                        .First().Value.ToString() == ":80:")
                    {
                        var root = child.Children
                            .Cast<DirectoryEntry>()
                            .FirstOrDefault(d => d.SchemaClassName == "IIsWebVirtualDir");
                        if (root != null)
                        {
                            result = root.Properties["Path"].Value.ToString();
                        }
                    }
                }
            }
            if (string.IsNullOrEmpty(result))
            {
                throw new Exception("Could not determine the default web.");
            }
            return result;
        }

Ever wish JavaScriptSerializer had a non-generic Deserialize method (like DataContractJSONSerializer)?

Well, Rex informed me of the handy MethodInfo.MakeGenericMethod which creates a constructed generic method, allowing us to avoid having to declare the generic types at design time.  So, now we can bolt on a Deserialize method (note, we cache the constructed generic methods) (formatted to appease wordpress)

public static class JavaScriptSerializerExtensions
    {
        private static object _lock = new object();
        private static IDictionary<Type, MethodInfo> _deserializers
               = new Dictionary<Type, MethodInfo>();

        private static MethodInfo GetDeserializeMethod(Type type)
        {
            lock (_lock)
            {
                if (_deserializers.ContainsKey(type)==false)
                {
                    var mi = typeof(JavaScriptSerializer)
                        .GetMethod("Deserialize");
                    _deserializers[type] = mi.MakeGenericMethod(type);
                }
            }
            return _deserializers[type];
        }

        public static object Deserialize(
               this JavaScriptSerializer serializer, Type type, string json)
        {
            return GetDeserializeMethod(type).Invoke(
                serializer, new object[] { json });
        }
    }

Get inspiration from .net’s LINQ in Javascript

When you think about working with enumerable stuff client-side, you can get great inspiration from .net’s awesome LINQ goodness.  For example, if you need a trivial way to sum up items in an array, you can bolt on a “sum” routine onto Arrays.  For example, here’s a small one, which has a default implementation to deal with strings or numbers:

Array.prototype.sum = function (predicate) {
    predicate = predicate || function (match) {
        if (typeof match == "string") {
            return match.length;
        }
        return match;
    };
    var result = 0;
    for (var i = 0; i < this.length; i++) {
        result += predicate(this[i]);
    }
    return result;
};

Here are a couple usage examples:

// Baked-in sum for strings
var array1 = ["hello","world"];
var length = array1.sum());

// Baked-in sum for numbers
var array2 = [10,20,30];
length = array2.sum();

// Custom for custom objects.
var array3 = [{yearsOfExperience:3},{yearsOfExperience:5}];
length = array3.sum(function(match){return match.yearsOfExperience;});

Here’s a Fiddle that demonstrates this (hit F12 in FF, Chrome, IE*+ and look at the console when running):  http://jsfiddle.net/harperj1029/Zeaqa/

Think Linq!

Use Powershell and Slickrun to display w3wp info

If you have multiple pools running within IIS locally, you’ll see corresponding w3wp.exe processes in visual studio when you try to attach for debugging purposes.  One quick way to figure out *which* one is the w3wp that you need to attach to is to display the process id and application pool for all the w3wp processes on your machine.  There’s plenty of old-school way to do that, or you can use a powershell script such as this:

gwmi win32_process -filter “name=’w3wp.exe'” | format-table -autosize name,processId,commandLine

So, you could pop that into a powershell file and call that either via an old-school batch file – or….. you could use a command line utility such as SlickRun and in-line the command into a “MagicWord” (Slickrun-speak for a named command) like this:

magic.

 

Of  course, this is pretty simple too: http://www.ervinter.com/2009/04/23/get-process-id-from-multiple-application-pool-iisapp/

Couple great tools for JavaScript and regex…

If you are whipping up some JavaScript and want a great place to build/run and perhaps share with other, then you need to check out JSFiddle.  This tool is fantastic, and a great way to collaboratively work on JavaScript.  For debugging and/or writing out to a console, consider using Firefox’s [awesome] firebug addin (IE Developer tools works pretty well too).

For times when you need to use regular expressions – and you’re either not strong at them, or have been away from them for more than 2 minutes (the time it takes to forget most of the syntax), then check out RegExPal.  This little utility is handy, and give great real-time visual indications of matches.