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