Getting My Attention Back

posted on 03/05/08 at 09:00:01 pm by Joel Ross

Attention equals time. It's really that simple. To give someone your attention, it takes time. If it doesn't take time, then you're not really giving them your full attention. And if you're not giving them your full attention, you're wasting everyone's time - yours and theirs.

That's been on my mind lately as I get involved in more and more things. IRC, Twitter, trying to keep up with writing blog posts, reading blogs, development, etc. And that doesn't even include the real important stuff - family. Some of those things aren't negotiable. Family and the job can't really get pushed away. Twitter is my current obsession. What I realized was that I was paying less and less attention to my RSS reader. Oh, I was "reading" a lot of posts, but if I was honest with myself, I didn't really read most of the posts. I scanned, and I scanned quickly. I was subscribed to 750 feeds after all!

So that's where I pushed back. I decided I wasn't getting anything out of reading blogs anymore, and that was disappointing, really. I used to get a ton out of reading blogs, but I wasn't picky about subscribing to new blogs - it was easy, so why not just keep adding?

Well, I found out why - it's too overwhelming. Since that time, I've cut my feeds down to 203 subscriptions. I'd like to get (and keep) that under 200, but I'm struggling to find the fat right now. And I'm taking the time to actually read what's important and interesting to me, which was the point, right?

So what did I cut? Mostly non-development blogs. Engadget made the cut, but a lot of other tech news sites were didn't, as well as blog media, blogs that don't update a lot, blogs that don't post about relevant topics, etc. Of the 203 left, not all of those are technical blogs - there's a few personal ones in there. But the technical ones are good and relevant.

Frankly, things are under control now, and I feel much less pressured to "keep up" since that's not as hard now, and when I do fall behind, it's not that hard to get caught up again.

Categories: Blogging, Personal


NuSoft Framework Background

posted on 03/04/08 at 08:37:50 pm by Joel Ross

Over the past few months, I've talked about the NuSoft Framework quite a bit, but after a twittersation (here, here, here, here, here, and here - Twitter needs threaded conversations!) with Matt Blodgett, I realized I've never really talked about what the motivation was for initially creating the framework. I've touched on it here and there, but nothing that I could point to and say "This is why we made the framework and why we use it over other options."

So let's start with the first - why did we even bother making the framework? There's plenty of other options out there, so why bother? Despite the fact that the framework became publicly available in the second half of 2007, it actually has it's roots at Sagestone back in 2003 or 2004. I started a new project, and it was against an existing database with 200+ tables. At the time, we debated typed datasets versus custom classes. The advantage that typed datasets provided was speed - creating them would be easy. You just imported your database and you were done, right? Yeah, except then you were stuck with the dataset's way of doing things.

So how could we justify using custom objects? Well, the only real way would be if we could quickly create those objects. One option was an O/R mapper, such as NHibernate. We considered a tool like that as others in the office were using them successfully. From my little experience with O/R mappers, it seemed that you still needed to create the objects and the mapping file. So really what you were saving was writing the SQL to persist your entities. Helpful, but that's still 200 classes to code up by hand, plus 200 mappings to create.

Better than all by hand, but not as efficient (from an up front development time) as datasets. As I started looking for easy ways to create the objects, I came across CodeSmith and a template that could create your hbm files. This was interesting, so I pulled down CodeSmith, which was free for generating code at the time. While my intent was to look into NHibernate, I started looking at the samples. Hmm. There was a sample to generate stored procedures for basic CRUD operations. There was a DAL template that worked with those stored procedures. And there was a simple model that got populated by the DAL. All were based on database tables. With a few modifications, that might work.

And so we tried it out. The time to generate all 200 classes was a little more than datasets would have been, but working with objects rather than datasets was much easier and more than made up for any speed advantage datasets had up front.

As I matured as a developer, I realized I wanted my entities to be much smarter than the model I'd been using. I slowly took those original templates and expanded them to be smart objects, tracking their own changes and ensuring they worked together to support transactions. I started looking into the CodeSmith API and figured out how to read relationships and started generating properties based on database relationships - Customer has a collection of Orders, Order has a Customer, etc.

At the same time, others inside of NuSoft (who, by that time, had acquired Sagestone) were doing something similar, but mostly by hand. And they had a base class that had some nice initialization methods for populating the entities. We eventually came together and over the course of a few lunch meetings and a lot of late nights, we came up with an early version of the framework. From there, we rolled it out internally. I gave presentations to both of our main offices and did a virtual meeting to get the word out. There, I laid out some of our core reasons for creating the framework (see, I'm finally getting to the point!).

Looking back at my rollout presentation, most of the reasons I listed were around being more efficient on our projects. From what we observed, there was a lot of variations from project to project, depending on who was in charge of the project. Our goal was to give every project the same basic framework to work against - that when you started a new project, you didn't have to worry about the technical details of saving or deleting objects, but you could focus on the domain problem - what the customer ultimately cares about. As a consulting company, our goal is to keep our bill rates up. One way to not do that is to charge customers to write CRUD code (that's Create, Read, Update, Delete - not cruddy code!). A side effect of this whole thing is that we're able to get new developers up to speed much quicker. First, they don't have to know the low level details to be productive, and second, as they explore the framework more and more, they learn the low level details - and since this is time-tested, they learn to do it correctly. And yes, I understand that "correct" is relative.

Anyway, if I boil our rollout to bullet points, here's the arguments:

  • Use Something. Part of this wasn't about the framework at all. We didn't want to force anything on anyone. We wanted to highlight that you can use it, and if you choose not to, you should have something else you are using. Where we're at in software development, it just doesn't make sense to handcraft repetitive, error-prone code.
  • Not Invented Here. NIH gets a bad rap, some of it deserved. In this case, it might be as well, but the bottom line was this framework was created based on how we'd already been doing things. Across most of the projects in our office, using the framework was a natural migration from what we'd been using - it felt familiar, just a bit more complete. By going with another tool, we'd have to get everyone trained on how this new tool worked, and when new features were needed, we'd be at the mercy of the project developers to add those. With the NuSoft Framework, since the developers were on staff, changes could be made much faster and tailored to suit our needs.
  • CodeSmith Usage. A lot of us had already been using CodeSmith, so creating the framework in CodeSmith was natural. We've considered converting to something else, but haven't seriously considered it because of what CodeSmith gives us. Along that same note, we already had partial templates in CodeSmith that we incorporate into the framework templates.

Notice that none of this answers why to pick it over something else. When we started, SubSonic was still called ActionPack, and when I first looked at it, I didn't care for the fact that it exposed data readers to the UI, which I don't care for. .NetTiers was a lot more bloated than we needed in most cases. LINQ wasn't even on the radar. Just about everything we looked at didn't do what we wanted the way we wanted to do it. Given we were over half way there based on what we already had, it wasn't that hard of a decision to do it ourselves. Add to that having the flexibility to be able to add to it without relying on others or forking from the base, and it wasn't really that hard of a decision.

I realize this does nothing for those starting fresh and wondering why they should choose the NuSoft Framework over something else. SubSonic has come a long way (but still exposes readers to the UI), and LINQ looks promising, even with the problems I've seen with LINQ to SQL. But I think questioning why we even bothered with the framework is a bit naive. It's like asking why there are multiple IoC frameworks out there, and new ones keep coming out. Just because something similar is already there doesn't mean there's not room for a new entry into the field, and, as you can see, we had our reasons for doing it.

I guess it really comes down to preference. Does the NuSoft Framework do things the way you want them to be done, or not? Is it a closer fit than the other options? If so, then it might be for you. If not, well, it certainly doesn't hurt that there's competition out there.

While we don't have a huge external user base, the ones that do are very supportive of our efforts. Internally, I'm constantly hearing about new projects that are using the framework successfully. At a recent internal meeting with 40-50 developers in the room, someone asked how many had used the framework, and just about everyone raised their hands, which completely took me by surprise.

I think that's enough of a rant. If you've used the framework, please feel free to add your thoughts about why you chose it over something else in the comments. If you chose something else, let me know what we're missing. I'd love to get the feedback.

Actually, I forgot the number one reason we made the framework - whenever we met, we got free lunch. I never pass up free lunches!

Tags: | | |

Categories: RCM Technologies


Retrofitting Code for the Web

posted on 02/27/08 at 02:45:06 pm by Joel Ross

Yesterday, Scott Reynolds posed a question about a problem he'd run into while making a web interface for his current project. The essence of his issue is that they have a static class that stores the current user and database connection string, and having that be static in a web application is problematic - it gets overwritten whenever someone new logs into the web site. My guess is his class looks something similar to this:

   1:  public static class Data
   2:  {
   3:     private static string _userId;
   4:     public static string UserId
   5:     {
   6:        get { return _userId; }
   7:        set { _userId = value; }
   8:     }
  10:     public static void SetUser(string userId)
  11:     {
  12:        UserId = userId;
  13:     }
  14:  }

He's got 200 classes that use this code, and doesn't want to modify all of those classes, so he asked if anyone had any input.

Well, we do something very similar to this on Tourneytopia, so I piped up, and provided him with a potential solution. I figured I'd share that here so anyone else who may run into this can see it as well.

The problem is not that the class is static. The problem is that the internal storage of the properties is static. Changing it slightly to allow for injection of a storage container will allow it to work with multiple users, while still allowing it to work without modification to the existing code base - the proposition of modifying 200 classes is pretty overwhelming! Here's the modified class:

   1:  public static class Data
   2:  {
   3:     private static string _userId;
   4:     public static string UserId
   5:     {
   6:        get 
   7:        {
   8:           if(_storage == null)
   9:           {
  10:              return _userId; 
  11:           } 
  12:           else 
  13:           {
  14:              return _storage.GetValue("UserId");
  15:           }
  16:        }
  17:        set 
  18:        { 
  19:           if(_storage == null)
  20:           {
  21:              _userId = value; 
  22:           }
  23:           else 
  24:           {
  25:              _storage.SetValue("UserId", value);
  26:           }
  27:        }
  28:     }
  30:     public static void SetUser(string userId)
  31:     {
  32:        UserId = userId;
  33:     }
  35:     private static IStorage _storage = null;
  36:     public static void SetExternalStorage(IStorage storage)
  37:     }
  38:        _storage = storage;
  39:     }
  40:  }

A few things to note about the update. First, it uses an interface (IStorage) to handle storage - as long as it's set. If it's not set, it defaults to the static fields it used previously - meaning the existing clients will continue working as they did in the past. New clients will call SetExternalStorage passing in an IStorage instance when the client loads (i.e., on initialization of the web site). I suppose you could have used an IoC framework to handle it, but that seemed like a bit of overkill to add that just for this.

The interface itself is pretty straight forward, and would reside in the same DLL as the static class above:

   1:  public interface IStorage
   2:  {
   3:     string GetValue(string key);
   4:     void SetValue(string key, string value);
   5:  }

This is a simple example, and you really could (should?) expand the interface to support specific properties that are in the static class - UserId, etc., so your IStorage provides typed access to information. But for simplicity, this will at least demonstrate the solution.

Now, in the web site, you'd implement this interface, using per-user storage as the internal storage mechanism. For this example, I'll use session:

   1:  public class WebStorage : IStorage
   2:  {
   3:     public string GetValue(string key)
   4:     {
   5:        return HttpContext.Current.Session[key].ToString();
   6:     }
   8:     public void SetValue(string key, string value)
   9:     {
  10:        HttpContext.Current.Session[key] = value;
  11:     }
  12:  }

Now the static class uses this class to store items, which store them per user - the ultimate goal.

The last thing you'd have to do is give the static class it's storage implementation on application initialization:

   1:  Data.SetExternalStorage(new WebStorage());

My initial version (for simplicity) used HttpContext in the static Data class directly, but requiring you to have a reference to System.Web in your business layer isn't a good idea, so I reworked it into what you see above.

In Tourneytopia, we use this same idea, but with a singleton, and instead of session, our storage lasts for the duration of the request, so we're really wrapping HttpContext.Current.Items.

Anyway, I'm not sure this is the best solution, or ultimately what Scott used, but it does seem to get the job done.

Categories: ASP.NET, Development, C#


Code Formatting

posted on 02/27/08 at 02:07:48 pm by Joel Ross

Sorry if you see this, but I needed to test code formatting from Windows Live Writer.


   1:  public static class Data
   2:  {
   3:     private static string _userId;
   4:     public static string UserId
   5:     {
   6:        get { return _userId; }
   7:        set { _userId = value; }
   8:     }
  10:     public static void SetUser(string userId)
  11:     {
  12:        UserId = userId;
  13:     }
  14:  }

Categories: C#


My Podcast List

posted on 02/26/08 at 09:51:23 pm by Joel Ross

Twice now, I've posted a list of podcasts I listen to (first time, second time), but I haven't posted an update in over two years. Today on Twitter, two people asked for some good podcasts, and while I answered, I figured I'd update my list, and include links. 140 characters isn't quite enough for that! Oh - and if you read the second one, it says I do my own podcast - I don't anymore!

Anyway - on to the list. I've separated them by audio and video.

  • DotNetRocks - this one has been on the list since day one, and even now that it's gone to twice a week, it's still one of the first ones I queue up.
  • Buzz Out Loud - This is a daily podcast about tech news. It's about 30-45 minutes long (officially it's an indeterminate length). Good way to stay on top of tech news, but you also get witty commentary.
  • CNET News Daily Podcast - It's daily as well - but about 10 minutes long. A lot of the same news as in BOL, but not much commentary - just straight news.
  • Diggnation - Not really sure this one will last very long. I realized their feed changed over the weekend and I haven't gotten an update since January 11th. If it takes over a month to even realize it, how important can it be? Either way, it's a review of some of the most popular stories on Digg. It's also available as a video. Once a week, usually 45 minutes.
  • Extralife Radio - Completely not tech. It's a show about video games, and the three guys have some good back and forth. Once a week, and about an hour.
  • Geek News Central - Another tech news review show. This has also been on my list since the beginning. It's twice weekly - Tuesday and Friday, and usually about an hour for each show.
  • Hanselminutes - Hosted by Scott Hanselman. Need I say more? His mantra is to not waste your time, and he never has. It's weekly and usually about 30 minutes. This show immediately heads to the top of the queue.
  • RunAs Radio - A spin off of DotNetRocks with Richard Campbell. It's more of an IT podcast, but it's good for developers to understand the infrastructure side, right? It's weekly, and usually about 30 minutes.
  • Mondays - Rarely posted, but great geek humor. When done, it's about an hour. It's with the gang from DotNetRocks.
  • Net @ Night - Leo Laporte and Amber MacArthur - It's weekly, and usually has some good interviews with people in the Web 2.0 world. A technical podcast, but not that technical.
  • Polymorphic Podcast - Craig Shoemaker hosts this one, and it's not exactly on a schedule. Shows seem to be few and far between. At one point, I was going to be interviewed on this show, but that fell through. It's usually very technical in nature. Usually about 30-45 minutes when it's posted.
  • The ASP.NET Podcast - Wally B. McClure hosts this one most of the time. Usually pretty technical, but not updated often. Does videos as well. Anywhere from 15 minutes to an hour.
  • The Gang (RSS Feed - group homepage is in Facebook) - Formerly the Gillmor Gang, it's hosted by Steve Gillmor and is roughly technical - from a high level standpoint. It can be extremely random and is more "stream of conscience" than a coherent, thought out show. Still, it's usually an interesting debate. The Gang itself is once a week, and is usually an hour or so. He's recently started NewsGang Live, which is daily and is usually about an hour as well. That one is much more political in nature, and whether I listen to it depends on who shows up that day and what they start talking about.
  • The Signal - Thomas Lewis and Mike Swanson host this one. I know Mike personally and have a great deal of respect for him, so that's part of the reason I listen to it. It's technical and relates to Mix '08. Not sure where it'll go (if anywhere) after that. Seems randomly published, and about a half hour when it is.
  • The Thirsty Developer - Dave Bost hosts this one. I told him I was stalking him at Mix '07, so it's only natural I'd listen to his podcast right?
  • This Week in Law - Decent discussion among lawyers about technology related news. I'm not a lawyer, nor would I ever want to be, but it's interesting to hear their take on current issues. Usually about an hour, and rarely published.
  • This Week in Media - Weekly. About an hour. Technology news that has a media slant - such as podcasts, online video, etc.
  • This Week in Tech - Leo Laporte and an assortment of "celebs" in the tech arena. Good tech discussions. Weekly, and about an hour.
  • Thoughtworks / IT Matters - Thoughtworks is thought leadership company, making some very cool products that are public, such as CruiseControl.NET. This is a podcast about a bit of their inner workings. It's usually about an hour, but episodes are few and far between - only three so far. Also, it's .m3a format. More on that later.
  • WebDevRadio - Very technical, but not necessarily .NET related. If I remember, it's about an hour, but sometimes shorter if it's just a quick update. Publishing isn't all that scheduled.
  • Engadget HD - A discussion of media - mainly video. It's from the Engadget folks, and it's pretty good. Weekly, and about an hour.


  • Code To Live - Josh Holmes hosts this one and it's usually pretty quick and a good topic. Completely relevant to what I'm doing.
  • dnrTV - Yet another podcast coming out of Pwop Studios. It's weekly and is a screen cast. Pretty much all code on a wide variety of .NET topics.
  • GeekBrief.TV - Cali Lewis hosts this. Roughly daily and short (3-4 minutes). Tech news, but sometimes pretty obscure tech news.
  • Wallstrip - Gotta keep a business sense right? CBS now owns it, and it's daily and short as well.
  • WebbAlert - Morgan Webb hosts it. Roughly daily and short (see a theme here?). Lots of video game news, but it's also got tech news as well.
  • Ask a Ninja - It's the same thing over and over, but it's hilarious! Random and short.

So how do I get through that many podcasts? Well, first, it may seem like a lot, but a few aren't published that often. Also, I don't focus on them - they are on in the background in my ears as I work or do the dishes or fold laundry, etc. And the best tip I can give you? Listen at 2x speed. It takes a bit to get used to at first, but once you are, you can get through podcasts a lot faster. Now, if just the Zune supported 2x, I could get that same efficiency while commuting to work.

Anyway, that's my list. What am I missing?

Categories: Podcasting


Personal Growth - Again!

posted on 02/20/08 at 11:21:54 pm by Joel Ross

I feel like I've been harping on this lately, but it's something I'm passionate about, so it's on my mind. Apparently I'm not the only one.

In our profession our real value is not the code we write but the problems we solve with it and our ability to adapt and improvise.  If you can't improvise you will eventually be replaced by the software that someone who can improvise has written that will automate what little you previously did.  And I will have no pity for you.  You could have taken some time now to read some blogs, or some books, or go to meetings, or a geek dinner, or join a mailing list, or do SOMETHING outside of your comfort zone that would have helped you grow.

Now is the time to take some action.  Get out of your comfort zone.  You'll thank me later.

I'm not sure I need to add anything here. Scott's done a great job expressing my thoughts.

Categories: Consulting, Personal, Development


Creating Your Own Provider Framework

posted on 02/20/08 at 12:53:51 am by Joel Ross

The Provider pattern is used in quite a few different locations in the .NET Framework (2.0). It's used for Membership, Roles, SiteMaps, and for encrypted configuration file sections. If you search around for help on them, you'll find quite a bit - but they are all pretty much about how to create your own provider for one of the already pre-built providers. There isn't much out there for framework developers who want to add a provider model to their own application.

As part of the NuSoft Framework, we went down the road of doing validation through a provider model, and I actually had a full-blown implementation of it that we're going to throw out. But before I do that, I wanted to document (for future reference) exactly what it takes to build your own provider framework.

There are 5 main pieces to create your own provider. I'll start with a high level view of what you need, walk through an example, and then dive into the details of each piece.

  1. Your abstract base provider class. This inherits from ProviderBase. All providers should be based on this class, so your custom one will have this as well.
  2. Your static provider class. This is what all end users will use. Internally, this will call the correct provider.
  3. Your provider configuration class. There's a configuration portion to most providers, and you can add custom information in there as well, so you'll need a custom configuration section.
  4. A provider helper class. This helps with the loading of your providers. If you know it's being used in a web application, there's a great one in the System.Web DLL. If you're not sure your provider will be used in a web site, then you probably don't want to reference System.Web just to get the helper class. I'll lay out what's in the helper so you don't need to rely on System.Web.
  5. A concrete provider. This is optional, but most providers supply at least one implementation of their abstract base provider class. It's up to you, and I'll show how you can be safe even if a provider isn't supplied.

As an example, let's look at Membership. There's an abstract class called MembershipProvider that defines the methods you'd need to implement if you were to make your own membership provider. Unless you do implement your own, you might never know about this class, because all client code calls the static Membership class - Membership.GetUser(), Membership.CreateUser(), etc.

To specify a membership provider, you Google for the config section you need, and add that. Most people use the SqlMembershipProvider, but there's also a MySqlMembershipProvider, and I think an OracleMembershipProvider. All of those classes are concrete implementations of the abstract MembershipProvider class.

So how does all of this work? Let's get into code, so you can see what needs to happen.

First, you have to define your contract - your abstract base class. Any method that you want your provider to handle should be included in this class.

   1:  public abstract class DataProvider : ProviderBase
   2:  {
   3:      public abstract void Get();
   4:      public abstract void Delete();
   5:  }

This is obviously not a real example, but the main thing to notice is 1.) It inherits from System.Configuration.Provider.ProviderBase, and 2.) no implementation is provided - all methods are abstract.

Next up is the static class that client code will use. The name is typically the same as the abstract class, minus the Provider part. Sticking to our (fake) example. we'd have a static class called Data.

   1:  public static class Data
   2:  {
   3:      private static bool _isInitialized = false;
   5:      private static DataProvider _provider;
   6:      public static DataProvider Provider
   7:      {
   8:          get
   9:          {
  10:              Initialize();
  11:              return _provider;
  12:          }
  13:      }
  15:      private static DataProviderCollection _providers;
  16:      public static DataProviderCollection Providers
  17:      {
  18:          get
  19:          {
  20:              Initialize();
  21:              return _providers;
  22:          }
  23:      }
  25:      private static void Initialize()
  26:      {
  27:          DataProviderConfigurationSection dataConfig = null;
  29:          if (!_isInitialized)
  30:          {
  31:              // get the configuration section for the feature
  32:              dataConfig = (DataProviderConfigurationSection)ConfigurationManager.GetSection("data");
  34:              if (dataConfig == null)
  35:              {
  36:                  throw new ConfigurationErrorsException("Data is not configured to be used with this application");
  37:              }
  39:              _providers = new DataProviderCollection();
  41:              // use the ProvidersHelper class to call Initialize() on each provider
  42:              ProvidersHelper.InstantiateProviders(dataConfig.Providers, _providers, typeof(DataProvider));
  44:              // set a reference to the default provider
  45:              _provider = _providers[dataConfig.DefaultProvider] as DataProvider;
  47:              _isInitialized = true;
  48:          }
  49:      }
  51:      public static void Get()
  52:      {
  53:          Initialize();
  54:          if (_provider != null)
  55:          {
  56:              _provider.Get();
  57:          }
  58:      }
  60:      public static void Delete()
  61:      {
  62:          Initialize();
  63:          if (_provider != null)
  64:          {
  65:              _provider.Delete();
  66:          }
  67:      }
  68:  }

There's a few things to note in this class. First, it has static methods for each method in the abstract provider class (Get and Delete). The internals of those calls all call Initialize, then checks if the provider isn't null, and if it's not, then makes the call. The initialize method is meant to only run once - it uses a variable to see if it's already been initialized, and if not, then it reads your configuration and loads the providers you've specified in the config. It uses a ProvidersHelper static class to do the actual loading, which we'll show in a bit. Once it loads all of the providers, it sets the default one that you specify, which is then used in the original call.

The code above expects that a configuration will be added to your application's config file, and if not, it will throw an exception. For something like data access, membership, etc., that may be the right call. For something like validation or an optional action, that may not be the best course. In that case, you could add a try/catch around the loading of the configuration (the Initialization method), and then either add a default provider implementation or have a default action in your static methods (it would be the else on if(_provider != null)).

While we're on configuration, we should look at the config section that would have to be added to the config file.

   1:  <configuration>
   2:     <configSections>
   3:        <section name="data" type="DataProviderConfigurationSection" />
   4:     </configSections>
   5:     <data defaultProvider="MyDataProvider">
   6:        <providers>
   7:           <add name="MydataProvider" type="MyDataProvider"  />
   8:        </providers>
   9:     </data>
  10:  </configuration>

In our Data static class, our initialize was looking for a section called data. In the config file, we need to define that section (the <configSections> element, and tell it what configuration section provider to use. Then we add the <data> section, specifying the list of providers and which one to use as the default. If you've looked at the Initialize method above, you'll see that we have a custom configuration section class.

   1:  public class DataProviderConfigurationSection : ConfigurationSection
   2:  {
   3:      public DataProviderConfigurationSection()
   4:      {
   5:          _defaultProvider = new ConfigurationProperty("defaultProvider", typeof(string), null);
   6:          _providers = new ConfigurationProperty("providers", typeof(ProviderSettingsCollection), null);
   7:          _properties = new ConfigurationPropertyCollection();
   9:          _properties.Add(_providers);
  10:          _properties.Add(_defaultProvider);
  11:      }
  13:      private readonly ConfigurationProperty _defaultProvider;
  14:      [ConfigurationProperty("defaultProvider")]
  15:      public string DefaultProvider
  16:      {
  17:          get { return (string)base[_defaultProvider]; }
  18:          set { base[_defaultProvider] = value; }
  19:      }
  21:      private readonly ConfigurationProperty _providers;
  22:      [ConfigurationProperty("providers")]
  23:      public ProviderSettingsCollection Providers
  24:      {
  25:          get { return (ProviderSettingsCollection)base[_providers]; }
  26:      }
  28:      private ConfigurationPropertyCollection _properties;
  29:      protected override ConfigurationPropertyCollection Properties
  30:      {
  31:          get { return _properties; }
  32:      }
  33:  }

It's pretty straightforward, but it helps define that we have a collection of providers and a defaultProvider property. You can add your own custom properties if you want - for example, for a data provider, you might want to specify either a connection string or the name of an existing connection string already specified. For this simple example, I don't have any of those.

I've already shown the usage of the ProvidersHelper class, but for completeness, I'll include it as well.

   1:  public static class ProvidersHelper
   2:  {
   3:      private static Type providerBaseType = typeof(ProviderBase);
   5:      /// <summary>
   6:      /// Instantiates the provider.
   7:      /// </summary>
   8:      /// <param name="providerSettings">The settings.</param>
   9:      /// <param name="providerType">Type of the provider to be instantiated.</param>
  10:      /// <returns></returns>
  11:      public static ProviderBase InstantiateProvider(ProviderSettings providerSettings, Type providerType)
  12:      {
  13:          ProviderBase base2 = null;
  14:          try
  15:          {
  16:              string str = (providerSettings.Type == null) ? null : providerSettings.Type.Trim();
  17:              if (string.IsNullOrEmpty(str))
  18:              {
  19:                  throw new ArgumentException("Provider type name is invalid");
  20:              }
  21:              Type c = Type.GetType(str, true, true);
  22:              if (!providerType.IsAssignableFrom(c))
  23:              {
  24:                  throw new ArgumentException(String.Format("Provider must implement type {0}.", providerType.ToString()));
  25:              }
  26:              base2 = (ProviderBase)Activator.CreateInstance(c);
  27:              NameValueCollection parameters = providerSettings.Parameters;
  28:              NameValueCollection config = new NameValueCollection(parameters.Count, StringComparer.Ordinal);
  29:              foreach (string str2 in parameters)
  30:              {
  31:                  config[str2] = parameters[str2];
  32:              }
  33:              base2.Initialize(providerSettings.Name, config);
  34:          }
  35:          catch (Exception exception)
  36:          {
  37:              if (exception is ConfigurationException)
  38:              {
  39:                  throw;
  40:              }
  41:              throw new ConfigurationErrorsException(exception.Message, 
  42:                  providerSettings.ElementInformation.Properties["type"].Source, 
  43:                  providerSettings.ElementInformation.Properties["type"].LineNumber);
  44:          }
  45:          return base2;
  46:      }
  48:      public static void InstantiateProviders(ProviderSettingsCollection providerSettings, ProviderCollection providers, Type type)
  49:      {
  50:          foreach (ProviderSettings settings in providerSettings)
  51:          {
  52:              providers.Add(ProvidersHelper.InstantiateProvider(settings, type));
  53:          }
  54:      }
  55:  }

There's a lot to this class, but it's something that you can copy and paste into your code base and use as-is. Basically, it looks at the config section, and finds providers you've added and dynamically loads them into memory. This works across assemblies - so if your provider is in DLL 1 and your provider implementation is in another, it will still load (assuming you specify the DLL in the type. It follows the standard format for that - type="My.Dll.Namespace.Class, My.Dll.Name").

The last piece is where you'll find the most help out there - implementing the concrete class for a provider.

   1:  public class MyDataProvider : DataProvider
   2:  {
   3:      public override void Get()
   4:      {
   5:          // Get Code
   6:      }
   8:      public override void Delete()
   9:      {
  10:          // Delete Code
  11:      } 
  12:  }

Again, this isn't a real implementation, so there's no real code here, but the idea is that your class inherits from your abstract class, and you implement the methods you've defined. I didn't have a need to, but in ProviderBase, there's a method called Initialize that gets called by the ProvidersHelper above. It allows you to grab any custom properties from your config sections to use in your provider.

You may have noticed there's a class that was mentioned above, but I never defined. In our static Data class, we have a collection of DataProviders, and it's type is DataProviderCollection. This is a simple class, so I didn't really mention it, but if you do your own, you'll want to know about it.

   1:  public class DataProviderCollection : ProviderCollection { }

The ProviderCollection is in the framework, and you can override methods in it to handle how providers are added to the collection.

With the above code, you can take that and implement your own provider for your own application. In a follow up post, I plan on showing how you can implement your own data provider as a way to cement the concept a bit more.

Tags: |

Categories: Development, C#


2008 Accenture Match Play Golf Bracketology Contest

posted on 02/18/08 at 05:23:14 pm by Joel Ross

Develomatic, LLC is running the 4th annual Accenture Match Play Golf Bracketology Contest, and once again, we are giving away a $25 Best Buy gift card to whoever makes the best picks.

We've added a few new features, but most of them are admin-focused, so not much has changed from a user perspective, so if you entered last year, it'll be similar. We've updated graphics, and added the ability to create private pools, so you can compete against a group of friends, and still compete in the overall competition.

So, if you're interested, hop on over and submit your picks. You've got until Wednesday morning. Even if you know nothing about golf, you've still got a chance - nothing ever goes as planned!

Tags: | | |

Categories: Sports, Develomatic


NFL Super Bowl Pick Review

posted on 02/07/08 at 09:00:21 pm by Joel Ross

Never have I been so happy about being wrong! I knew I should have picked the Giants (at least to cover - New England didn't cover in their past two Super Bowl appearances either). But nope. Didn't do it. Still, I was thrilled to see New England lose. And it was nice to see Eli Manning step up and lead his team late in a huge game. Plus, back to back Super Bowls for Mannings!

  • New York Giants 17, New England 14 (-11.5) (53.5 O/U) [P: ($10.00), S: ($10.00), O/U: $9.09, T: ($10.91)]: There's three plays that stick out in my mind in this game. 4th and 13 for New England. The catch by David Tyree (plus, the escape by Manning). The catch by Plax (an MSU guy. Notice it wasn't that other receiver from that other school).

I plan to post a summary of the season and my results, but I'll do that later.

Tags: | |

Categories: Football


This Is What Makes It All Worth It

posted on 02/06/08 at 10:52:25 pm by Joel Ross

Today, we met to figure out what's left for v3 of the NuSoft Framework. We're close - another week or two and we should be ready. We had a few heated discussions over a couple of points, but in the end, we figured it out.

This is something that a few of us at NuSoft have decided is worth our efforts, even though we don't get dedicated time to work on it. We're using it internally at NuSoft on a lot of projects, so we get good feedback internally, but we haven't gotten a ton from external sources. We don't really know how many (if any) are using it.

Which lead me to wonder recently if it's worth the effort to put this out - it's more effort to do this in a public setting rather than an internal setting. And just as I'm starting to wonder about that, we get this:

I am writing a custom software application for someone and I had the NuSoft Framework recommended to me. The only problem is the framework is designed for a SQL database and due to the constraints of the system I needed to use an Access database. But I decided to give the framework a try anyways. So I changed my Access datababse into a SQL database in order to generate the code and after I generated the code I had to make some modifications so it would run against the Access database. It only took me a few hours to make some of the changes just to get it going, but once I had made some changes it was super easy to use and it is amazing. It has saved me so much time and even though I find I need to change some of the SQL statements to work properly it is wonderful. Thank you so much for releasing it. It has saved me hours of work.

And that right there is why I do it!


Categories: RCM Technologies


<< 1 ... 9 10 11 12 13 14 15 16 17 18 19 ... 124 >>