Monday, May 18, 2009

Garbage Collector

Ran into a scenario this past week with the GC.

Take this example:

   1: public void Method1()
   2: {
   3:     object o = new object();
   4:     // Do Some work WITH o;
   5:  
   6:     // Do Some work WITHOUT o;
   7:     o = null;
   8: }
   9:  
  10: public void Method2()
  11: {
  12:     object o = new object();
  13:     // Do Some work WITH o;
  14:  
  15:     // Do Some work WITHOUT o;
  16: }

With method is more efficient?

At first glance you would say Method1 since it “cleans up” its variables.  Lets say o was actually a SqlConnection.  We would want to clean that up at the end of the scope right?

Maybe not, turns out the garbage collector in .NET is smarter than us.  In Method2, we don’t reference o after we are done using.  Since it isn’t ever used again the garbage collector will come along and clean it up for you before the method ends.  Pretty slick right?  Declare, use, forget… and I get the optimum effect for free.  Back to o being a SqlConnection, since o “may, if resources are needed or the os has some free time”, the connection will get cleaned up quickly.

Now, for the rub…

I was a good little developer and made sure the cleanup of my RootDisposable cleaned up its ChildDisposable when it was cleaned up.

   1: internal class RootDisposable
   2:     : IDisposable
   3: {
   4:     protected ChildDisposable MyChild { get; private set; }
   5:  
   6:     public ChildDisposable GetMyChild()
   7:     {
   8:         if(MyChild == null)
   9:             MyChild = new ChildDisposable();
  10:  
  11:         return MyChild;
  12:     }
  13:  
  14:     #region IDisposable Members
  15:  
  16:     protected void Dispose(bool disposing)
  17:     {
  18:         if (MyChild != null)
  19:         {
  20:             MyChild.Dispose();
  21:             MyChild = null;
  22:         }
  23:     }
  24:  
  25:     public void Dispose()
  26:     {
  27:         Dispose(true);
  28:         GC.SuppressFinalize(this);
  29:     }
  30:  
  31:     ~RootDisposable()
  32:     {
  33:         Dispose(false);
  34:     }
  35:  
  36:     #endregion
  37: }

I was also a good developer in that I implemented the Disposal pattern where the Finalizer calls Dispose(false), which will cause my child object to get cleaned up then also.

Now, for the cherry on the sundae, I built my app in Release mode for my customers, deployed it, and it broke for them.  WTF!?  (At this point blame QA, they should have tested the Release version instead of the debug! :D)

Check out the the trunk\Samples\AggressiveGarbageCollection sample in my codeplex site coderjoe.codeplex.com for sample that you can use to play around with this.  Just remember the code will only fail if you build it in Release mode :)

I snagged my GC collect code from example in GC.KeepAlive method in the msdn docs.

Friday, May 15, 2009

View – ModelView – Model+Controller… In that order!

So spinning along with Results-Driven.

Where to start your application design.  I’ve always started with the database.  Then used my tools to generate the model, apply my methods to the objects.  Build out the GUI, fix the bugs, and then release.  Smooth as chocolate silk pie :)

Maybe not, you end up spending forever trying to make your customer happy with the results.   My biggest annoyance is to have to tell my customer “It can’t work that way”.  I like to be the yes-man.image

Starting with the GUI or the View avoids this situation.

From there you can start working on the ModelView.  The model view is doing two things for you at this point.  Giving you mocks to test your GUI, and also defining the “grain” of the application.

Understanding the “grain” of the application is important.  Too many times starting at the database level I created schema’s that were so fine grained they were almost unusable.  Models of 3rd, 4th and maybe even 5th level normalization.  Which in turn gave me super bloated business layers, and horrendous GUI’s.

Moving down the chain, the Model+Controller come into play next.  The model should just be data, the controller should be the methods to perform actions. 

So for a ModelView you might have an object like.

   1: public class ModelView
   2: {
   3:     public int Id { get; set; }
   4:     public string Name { get; set; }
   5:     public string Email { get; set; }
   6:     public bool IsNew { get; set; }
   7:  
   8:     public void New();
   9:     public void Load(int id);
  10:     public void Save();
  11: }

Based on the above ModelView, which is already wired up to the GUI, we can surmise that our Model+Controller needs at the very minimum.

   1: public class Model
   2: {
   3:     public int Id { get; set; }
   4:     public string Name { get; set; }
   5:     public string Email { get; set; }
   6: }
   7:  
   8: public class Controller
   9: {
  10:     public Model Get{int id);
  11:     public Model Create(Model model);
  12:     public Model Update(Model model);
  13: }

All that is left is to wire up our Model+Controller, as long as the user’s feedback was taken into consideration during the View-ModelView timeline, we should have a working app that everyone is happy with.  Plus 2 layers of flexibility, database changes can be worked out in the controller or service layer.  Gui changes can be worked out in the View-ModelView, and then flowed down through the rest of the system.  All is good in the world again.

The first time I took the GUI-First approach, was a Time-Entry system.  The module for the ERP system had everything we wanted, but the time entry system sucked.  Since I already had the tables the data had to fit into, I saw it as a challenge to let the users go wild with the gui.  I tried to put in all the nifty little short-cut items to help them enter their time as fast as possible.

The application was a phenomenal success.  The users loved the gui, and I mean loved it.  I was instantly promoted to Hero status.

Code can be found in trunk/Samples/View-ModelView-Model+Controller on my codeplex site coderjoe.codeplex.com.

Thursday, May 14, 2009

Developing Expertise: Herding Racehorses, Racing Sheep

A friend sent me this video today.  I would have ignored it as I usually do, but this is one of the authors of The Pragmatic Programmer.  If you haven’t read the book, buy it, read it and then share it with your peers.  When they don’t give it back, go buy another copy (this one you don’t have to share :)

http://www.infoq.com/presentations/Developing-Expertise-Dave-Thomas

So what level are you?

More recently I’ve had to put my supposed “humility” aside and accept the fact that I am in the “Expert” category.  This blog is part of that acceptance.

Time to put myself out there towards the criticisms of my peers, and hopefully help others out in the process.

Tuesday, May 12, 2009

Services as Classes and WCF Services

Taking a break from my "results oriented theory"...

I like services, I like the ability to call the same API’s remotely as I would call inside a website that I develop. The issue I have with this is overhead. And not just service call overhead, there is configuration overhead, debugging overhead and a slew of little things that all have to be aligned in order for things to work right.

Add on top of that I end up doing double duty. I hit the database to load up a context with items I expect to work with, then pass those items to a service which has to requery the same objects back out to do their work. Considering my web server is only 1 hop away from my database this seems pointless.

So what I want, is a way to construct a class that can be used like a the service would when it is constructed as a local heap object, and also use that same class to run as a service. Depending on how the class is hosted it changes some of its functionality. Take this simple service interface.

   1: [ServiceContract]
   2: public interface ISampleService
   3: {    
   4:     [OperationContract]    
   5:     User FindUserByUserId(int userId);
   6: }
   7:  

And the implementation

   1: public partial class SampleService
   2:     : ServiceBase
   3: {
   4:     protected SampleModelContainer Context { get; private set; }
   5:  
   6:     protected SampleService()
   7:     {
   8:     }
   9:  
  10:     public SampleService(SampleModelContainer context)
  11:     {
  12:         if (context == null)
  13:             throw new ArgumentNullException("context");
  14:          Context = context;
  15:     }
  16:  
  17:     public User FindUserByUserId(int userId)
  18:     {
  19:         return
  20:             (from u in Context.Users
  21:              where u.UserId == userId
  22:              select u).FirstOrDefault();
  23:     }
  24:  
  25:     protected override IDisposable CreateServiceContext()
  26:     {
  27:         Context = new SampleModelContainer();
  28:  
  29:         return new DisposableContainer(
  30:             Context);
  31:     }
  32: }

Notice the empty constructor is “protected”, WCF can use the protected constructor when instantiating this as a service, however our web code will use the constructor with the “context” parameter passing in our database context.

And now we see the problem. The service based instance won’t have a database context to run against. FindUserByUserId will fail with a NullReferenceException.

We could just construct the Context in the constructor, but what fun is that. So what we need is a way to wrap our service calls. For starters I have the CreateServiceContext() call, this is where you put your creation logic for a service call. Its wrapped in an IDisposable so all your cleanup will occur at the end of the method call. So for my service calls I implement an Invoke on the base using a delegate to call the original method on the class.

   1: public abstract class ServiceBase
   2: {
   3:     protected virtual IDisposable CreateServiceContext()
   4:     {
   5:         return null;
   6:     }
   7:  
   8:     protected virtual void HandleServiceException(Exception ex)
   9:     {
  10:         throw ex;
  11:     }
  12:  
  13:     protected TResult Invoke<TResult>(Func<TResult> func)
  14:     {
  15:         try
  16:         {
  17:             using (CreateServiceContext())
  18:             {
  19:                 return func();
  20:             }
  21:         }
  22:         catch (Exception ex)
  23:         {
  24:             HandleServiceException(ex);
  25:         }
  26:  
  27:         return default(TResult);
  28:     }
  29: }

I have a HandleServiceException virtual method in case I want to custom wrap exceptions. Lets say I want to throw an ArgumentException when the method is invoked in web code, but I want that wrapped into an FaultException<ArgumentFault> in the service. I would put that code in the HandleServiceException.

Now, to implement the service interface explicitly and forward the calls through the invoke.

   1: partial class SampleService
   2:     : ISampleService
   3: {
   4:     #region ISampleService Members
   5:  
   6:     User ISampleService.FindUseryByUserId(int userId)
   7:     {
   8:         return Invoke<int, User>(FindUserByUserId, userId);
   9:     }
  10:  
  11:     #endregion
  12: }

And there we have it, a service class that is context bound when running from the heap, yet single-call when running in a service host.

Now to move a step beyond, we may need to change the way the service works based on parameters. Inside the service hosted environment we will expect the user to provide scope parameters. While being called as a local heap object we can provide those parameters as part of the construction of the object.

The class implementation

   1: public partial class SampleService2
   2:     : ServiceBase
   3: {
   4:     protected SampleModelContainer Context { get; private set; }
   5:     protected int PlatformId { get; private set; }
   6:     protected Platform Platform { get; private set; }
   7:  
   8:     protected SampleService2()
   9:     {
  10:  
  11:     }
  12:  
  13:     public SampleService2(SampleModelContainer context, int platformId)
  14:     {
  15:         if (context == null)
  16:             throw new ArgumentNullException("context");
  17:  
  18:         Context = context;
  19:         PlatformId = platformId;
  20:     }
  21:  
  22:     public SampleService2(SampleModelContainer context, Platform platform)
  23:     {
  24:         if (context == null)
  25:             throw new ArgumentNullException("context");
  26:  
  27:         if (platform == null)
  28:             throw new ArgumentNullException("platform");
  29:  
  30:         Context = context;
  31:         Platform = platform;
  32:         PlatformId = platform.PlatformId;
  33:     }
  34:  
  35:     protected override IDisposable CreateServiceContext()
  36:     {
  37:         Context = new SampleModelContainer();
  38:  
  39:         return new DisposableContainer(
  40:             Context);
  41:     }
  42:  
  43:     public IEnumerable<User> FindUsers()
  44:     {
  45:         ValidatePlatform();
  46:  
  47:         return
  48:             (from u in Context.Users
  49:              where u.Platforms.Contains(Platform)
  50:              select u);
  51:     }
  52:  
  53:     private void ValidatePlatform()
  54:     {
  55:         if (Platform != null)
  56:         {
  57:             Platform =
  58:                 (from p in Context.Platforms
  59:                  where p.PlatformId == PlatformId
  60:                  select p).FirstOrDefault();
  61:         }
  62:  
  63:         if (Platform == null)
  64:             throw new Exception("Invalid Platform");
  65:     }
  66: }

In this service we expect to only operate on a single platform level. From a service call we must determine that context from the method call, from the web code we know that earlier and sending it in via the constructor is more prudent.

The ValidatePlatform() is invoked in methods that we want to ensure we have a platform bound before we begin our work.

Now for the service interface

   1: [ServiceContract]
   2: public interface ISampleService2
   3: {
   4:     [OperationContract]
   5:     IEnumerable<User> FindUsers(int platformId);
   6: }

And the service interface implementation

   1: partial class SampleService2
   2:     : ISampleService2
   3: {
   4:     #region ISampleService2 Members
   5:  
   6:     IEnumerable<User> ISampleService2.FindUsers(int platformId)
   7:     {
   8:         PlatformId = platformId;
   9:  
  10:         return Invoke<IEnumerable<User>>(FindUsers);
  11:     }
  12:  
  13:     #endregion
  14: }

Notice the platformId is sent in via the method call. This scoping parameter gets converted to the service property in the explicit interface implementation.

I’ve been using this technique for a few months now on my services. And it has been pretty slick. The composition capabilities of my services is insane, but I’ll save that for a future article.

Another bonus of this technique is testing. Since the core of the service gets exercised both through the testing of our app via WCF and through direct invocation from the websites.

Check out my codeplex project coderjoe.codeplex.com to browse through the full solution.

Find it in Source Code –> Browse –> trunk/Samples/ServiceObjects