Monday, June 10, 2013

Adhering to the DRY Principal in Javascript/Knockout

One of the things that honestly "hurt my feelings" when developing an HTML5 replacement application awhile back - was that the ViewModel needed to be declared in multiple places. Once in the service and again in the client. Of course, all the demonstrations during tech-week seemed to gloss over this with very simplistic applications. Required reading - Pragmatic Principles
Now, there may be ample reason to want to do this -> what I'm enacting upon in the client may require a subset (possibly?) but I would contend that it should probably be a different service call. Don't transfer bytes that you don't need! So I created a static class helper to be used within a Razor template - and proceeded to forgot all about it. 
A colleague from another department heard about/asked me about it and I rediscovered it. Enjoy. As always YMMV. If you improve on it - share it. I'll laud you copiously.

The helper:
public static class HtmlHelper
    {
        private static string JavaScriptify(string s)
        {
            return string.Join(".", s.Split('.').Select(x => x[0].ToString().ToLower() + x.Substring(1, x.Length - 1)));
        }

        public static IHtmlString KnockoutFrom<T>(this HtmlHelper<T> html, T obj)
        {
            var serializer = new JsonSerializer
                                 {
                                     ContractResolver = new CamelCasePropertyNamesContractResolver()
                                 };

            var sb = new StringBuilder();
            sb.Append("(function() {");

            var json = JObject.FromObject(obj, serializer);

            sb.Append("var vm = ko.mapping.fromJS(" + json + ");");

            var type = obj.GetType();

            var ns = JavaScriptify(type.Namespace);
            sb.Append("namespace('" + ns + "');");
            sb.Append(ns + "." + JavaScriptify(type.Name) + " = vm;");

            sb.Append("})();");

            return new HtmlString(sb.ToString());
        }
    }


The template:
@Html.KnockoutFrom(Model)

Friday, May 17, 2013

WSDL service returning DataSet? Seriously?

Just got a 'last-minute' TODO - have to establish another interface for state agency. Like any good developer - I grab the WSDL and 'prop-up' a test service. Imagine my surprise when I see the defined method results as DataSet. Yup. Can be anything - based on nature of the "select" - egads. 

The ONLY reasonable  - and its by NO MEANS reasonable - "theory" that *might* explain this 'design' decision is that auto-generated proxies won't 'break'. (Yea. It's a lame excuse and kinda defeats the purpose of contract-first development) Besides, auto-generated proxies are for the faint-hearted (HTTP/XML for me).

How to generically 'mock' a dataset? Grab NBuilder from NuGet and add to your project. Then add a POCO representation of the fields you wish to return. Then call this:
private static DataSet CreateDataSet<T>(int numberOfRows = 1)
        {
            var datatable = new DataTable(typeof (T).Name);
            typeof (T).GetProperties().ToList().ForEach(
                x => datatable.Columns.Add(x.Name));
            Builder<T>.CreateListOfSize(numberOfRows).Build()
                                    .ToList().ForEach(
                                        x => datatable.LoadDataRow(x.GetType().GetProperties().Select(
                                            y => y.GetValue(x, null)).ToArray(), true));
            var dataset = new DataSet();
            dataset.Tables.Add(datatable);
            return dataset;
        }

soapUI tests against WSDL methods work - now 'back-to-work'!

Tuesday, May 14, 2013

More Hibernation Fun :: Dialect does not support variable limits.


Had a sad-panda moment when I went to Linq to NHibernate with the following (rather straight-forward) syntax.

...

 var e = r.Where(w => w.Name.Contains(searchBy)).Select(c => c).Take(5).ToList();  
...
I bombed out on a simple test - with the exception being "Dialect does not support variable limits." Rather broad base of Google hits on this one...

Seemed like something wrong with the underlying dialect - so I needed to override; something like this:
 public class FixedMsSqlDialect : NHibernate.Dialect.MsSql2005Dialect  
   {  
     public override bool SupportsVariableLimit  
     {  
       get  
       {  
         return true; //because SQL Server DOES support TOP selects  
       }  
     }  
   }  

...


What was unclear was "where" does that go? Quick breeze through source revealed that it was 'set' right after the IPersistenceConfigurer was instantiated - so static method to use for my fluent configuration.
... 


 private static IPersistenceConfigurer PersistenceConfigurer(string connection)  
     {  
       var provider = MsSqlConfiguration.MsSql2005.ConnectionString(connection);  
       provider.Dialect<FixedMsSqlDialect>();  
       return provider;  
     }  
...

Now based on connection string - I can inject the "home-grown" default behavior from my GetConfiguration method.

...
 public FluentHelper(string connectionKey, bool autoConfig = false)  
       : this(  
         () =>  
         Fluently.Configure()  
         .Database(GetConfigurationOption(connectionKey))  
         .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))  
           .ExposeConfiguration((c =>  
           {  
             if (autoConfig)  
             {  
               BuildSchema(c);  
             }  
           })).BuildSessionFactory())  
     {  
     }  
 private static IPersistenceConfigurer GetConfigurationOption(string connectionKey)  
     {  
       string connection = ConfigurationManager.ConnectionStrings[connectionKey].ConnectionString;  
       switch (ConfigurationManager.ConnectionStrings[connectionKey].ProviderName)  
       {  
 ....omitted for brevity  
           default:  
             return PersistenceConfigurer(connection);  
       }  
 }  

Hurray - Linq Take() actually works now.



Sunday, May 12, 2013

NHibernate 3.x changes


Working on a sample project for a perspective company - when enabled NuGet for FluentNHibernate, and saw a breaking change in the NhQueryable constructor. (I've been building from the source for awhile so this one passed me by, 2.x - 3.x introduced some breaking changes)

This breaks:
...
public ReadOnlyRepository(ISession session)
        {
            this.selection = new NhQueryable(session);
        }
....

This 'seemed' to work - at least the compiler didn't complain:
...

public ReadOnlyRepository(ISession session)
        {
            this.selection = new NhQueryable(session as ISessionImplementor);
        }
...

After a few unit-tests later I discover that the session passed in is NOT being preserved. Now what?

So I look at the IQueryOver interface - inside of Hibernate seems to add some Extension methods and a Linq-like interface; but I miss the more "natural" feel of regular Linq expressions. Granted, I won't have as much fine-control over the underlying query - but I'm not doing anything too crazy - yet.

I end-up changing the original interface/implementation from:
 public interface IReadOnlyRepository where TEntity : class  
  {  
      IQueryable Linq();  
  }  
...
#region IReadOnlyRepository Members

         public IQueryable Linq()
  {
   return this.selection.AsQueryable();
  }

#endregion
...

to the 3.x friendly:

public interface IReadOnlyRepository : IQueryable where TEntity : class
    {
        IQueryable AsQueryable(); 
    }
...

Note: The implementation then explicitly marshals the "queryable-ness" to my preserved session.

Also Note: the explicit usage of namespace System.Linq - otherwise it WILL conflict with Hibernate:

#region IReadOnlyRepository Members

        public System.Linq.IQueryProvider Provider
        {
            get { return session.Query().Provider; }
        }

        public System.Collections.Generic.IEnumerator GetEnumerator()
        {
            return session.Query().GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public System.Type ElementType
        {
            get { return session.Query().ElementType; }
        }

       public System.Linq.Expressions.Expression Expression
        {
            get { return session.Query().Expression; }
        }

        public IQueryable AsQueryable()
        {
            return session.Query();
        }
        #endregion

Turns out this tripped out quite a few, as I searched the web. Hope this helps someone transitioning from building from source to moving to NuGet.

Why did I ever switch to MSTEST?

Ran into a wicked problem with MSTEST today, resurrected an old project went to run the tests - and boom - nothing appeared to run - very similar to the "cylon" symptom I talked about in 2010. Eventually ran into this wonderment which gave me at least an indication of what was happening (and only 2 days after latest VS2012 update too...hmmm)



So I waded through the following links to try and discover what was happening...

Came across a number of Open, Closed and Unreproducable issues from Microsoft Connect. Then finally a Resharper related post seemed like it was worth trying out (super shoutout to JetBrains forums). 

So I ended up switching from MSTEST to NUNIT and all tests ran. (Big Surprise)
I am reminded of an old song going back to NUNIT...

So how to switch in between NUNIT/MSTEST quickly - use a build directive - NUNIT.
Add the following code to the the head of your test files (or possibly a partial class, or just a plain base-class that all test files inherit from). Then you are basically remapping the MSTEST attributes to the appropriate NUNIT ones. You are rocking with NUNIT - thank you Resharper & StackOverflow. 
(Note: There is no TestContext available in NUNIT so if you rely heavily on that you will have to do something else)


#if NUNIT
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endif

StackOverflow

http://osherove.com/blog/2010/3/5/nunit-vs-mstest-nunit-wins-for-unit-testing.html

Sunday, September 23, 2012

Entice Me
Opening my eyes and looking around to see what is available. Willing to relocate for the right opportunity or area (I like the coast). I bring a great deal to the table and I'm kinda fun to work with...let's see what we can do for each other.

Curriculum Vitae/Resume
Zerply-Profile