Thursday, August 1, 2013

I wish I understood when to use C# attributes better.

What is a good pattern to apply them in? Why should I care? I tried to refactor static state stuff like this to make it use attributes, but I know I just made things more complicated than they needed to be. Here is what I attempted. I made a data transfer object...

namespace MvcApplication.Models
{
   public class Dto
   {
      public int NumberOfDaysInTheWeek { get; set; }
      public string WhoIsBuriedInGrantsTomb { get; set; }
      public bool IsEarwaxTasty { get; set; }
   }
}

 
 

...which may live in static state.

namespace MvcApplication.Models
{
   public static class GlobalState
   {
      public static Dto Settings { get; set; }
   }
}

 
 

Let's make that globally available static state. Here is how Settings on GlobalState gets set:

using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using MvcApplication.Models;
namespace MvcApplication
{
   public class WebApiApplication : System.Web.HttpApplication
   {
      protected void Application_Start()
      {
         GlobalState.Settings = new Dto()
            {
               NumberOfDaysInTheWeek = 7,
               WhoIsBuriedInGrantsTomb = "Grant",
               IsEarwaxTasty = false
            };
         AreaRegistration.RegisterAllAreas();
         WebApiConfig.Register(GlobalConfiguration.Configuration);
         FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
         RouteConfig.RegisterRoutes(RouteTable.Routes);
         BundleConfig.RegisterBundles(BundleTable.Bundles);
      }
   }
}

 
 

Alright, I can gets bits of Settings on GlobalState back in a Controller by doing way too much work like so:

using System;
using System.Web.Mvc;
using MvcApplication.Models;
namespace MvcApplication.Controllers
{
   [Settings]
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         int numberOfDaysInTheWeek = ((SettingsAttribute)Attribute.
               GetCustomAttributes(this.GetType(), typeof(SettingsAttribute))[0]).
               Settings.NumberOfDaysInTheWeek;
         return View(numberOfDaysInTheWeek);
      }
   }
}

 
 

I suppose if I really wanted to nurture this anti-pattern all of my Controllers would inherit from a middleman base class which would inherit from Controller and the middleman would have the SettingsAttribute decorating it. Anyways, SettingsAttribute looks like this:

using System;
namespace MvcApplication.Models
{
   [AttributeUsage(AttributeTargets.Class)]
   public class SettingsAttribute : Attribute
   {
      public Dto Settings { get; set; }
      public SettingsAttribute()
      {
         Settings = GlobalState.Settings;
      }
   }
}

 
 

What am I doing wrong? What should I be doing instead? Thoughts?

No comments:

Post a Comment