Invoke base class methods on unknown types

I recently built a system that dynamically builds content for sending messages to users after certain events.  As is with most of these types of systems the content is mostly static and stored in a repository with “holder values” that are replaced at run time from a data source.  The architecture of this system is one that is very configurable.  Meaning, a new message can be created using configuration files no additional coding necessary.  One of the challenges this presented was how to handle formatting of data types that are not known until run time.

Use Case:

The content may look something like: “Your bill with a billing date of _date for _amount is overdue.”  The holder values are _date and _amount; the data source might store the amount as a number and the date including the time (100 & 12/31/2012 08:35:55).  However, this data would need to be formatted as $100.00 and 12/31/2012 for a user facing message.

The system needed to handle any possible formatting of data without knowing at build time what they might be.  To accomplish that I store a pointer to a data source for each “holder value”, which includes a mapping to a base class method (and the required parameters) of the underlying data type.  Then, when replacing holder values with the  real values from the data source I apply the method using reflection.

Here’s some sample code and a quick explanation:

public static string InvokeSomeMethod(string method, string parameters, string value)

        {
            Object v = ConvertValue(value);
            var pList = ParseMethodParameters(parameters);
            var rt = v.GetType().GetMethod(method, GetParameterTypes(pList)).ReturnType.FullName;
            return InvokeMethod(v, rt, method, pList);
        }
}

“Let me explain. No, there is too much. Let me sum up”:

We can’t just invoke a method all willy nilly like, first we need to know a few more things.

  • What type are we dealing with?
  • What is the return type of the method? (Beware of overloads)

A little more detail:

Type:

The values I’m dealing with are strings, however, I may need to execute a method on it’s “true” type.  In order to get the type I call ConvertValue (line 1 above) which passes the value through a series of tests to determine what type it is and convert it.  I won’t bore you with the entire method, but this should give you an idea what I mean.

 public static object ConvertValue(string value)
        {
            if (ParameterIsInt(value))
            {
                return Convert.ToInt32(value);
            }
            if (ParameterIsDouble(value))
            {
                return Convert.ToDouble(value);
            }
              if (ParameterIsDate(value))
            {
                 return Convert.ToDateTime(value);
            }
        }
}

Each sub-function does something like this:

 public static bool ParameterIsDate( string value)
        {
            DateTime d;
             bool result = DateTime.TryParse(value,  out d);
             if (result)
            {
                 return true;
            }
             else
            {
                 return false;
            }
        }

Return Type and the Parameter List:

Remember above where I said beware of overloads when getting the return type.  The parameter list has to be parsed and passed when getting the method return type in order to get the correct method. When I parse the list I reuse the convert value function to get the correct type of the parameter, this is key to the getting the method.  And of course the parsed parameters are passed when invoking the method.

Conclusion:

So far this method (as part of a larger highly flexible system) has worked very well and allowed us to create a lot of new content with little to no new lines of code.  One down side, the person building the configurations has to  know the base class methods and parameters (absent a user interface for the content management) to format the data.  Another issue was the convert value function.  When I originally built the system I just added the half dozen or so common data types.  However, if a new one comes up some coding will have to be added.  I do have a possible solution to that issue.  In some other similar systems I’ve used Convert.Change Type to change strings to the “real type”.  This works well as long as you know what type you want.  If not, your still forced to call the various try parse methods to get the type.  In a system like the one were using, we could leverage the configuration to pass a type to the Convert.ChangeType method and get rid of the try parse convert to methods.  I’ll probably add that the first time I have a new data type come up, so far it hasn’t.

Advertisements

Extension Methods and Generics: Match a String To a Enum

To match a string value to a enum you have a couple options.

  1. You could loop through the enum values until you find a match.
  2. Or a better option, use the Enum.Parse method to convert the string to the equivalent enumerated object.

However, when exchanging data with third parties you might find the need to convert between strings and enums often.

With a little help from generics I wrote a quick extension method to make this even easier.

Example:

public static T FromStringToEnum<T>(this String stringValue, T enumToGet)
{
    if (!typeof(T).IsEnum) return default(T);
    return (T)Enum.Parse(typeof(T), stringValue); 
}

public enum Number { one, two }

[TestMethod]
 public void FromStringtoEnum_EnumReturned()
{
    string f = "one";
    var e = f.FromStringToEnum( new Number());
    Assert.AreEqual(Number.one, e);
}

[TestMethod]
 public void FromStringtoEnum_NonEnumPassed_DefaultReturned()
{
    string f = "one";
    var e = f.FromStringToEnum("");
    Assert.AreEqual( null, e);
}

The first line validates that T  is an Enum, if not it will return the default value of the type.   The second line is the implementation of the parse method using generics to get the type of the enum.


			

Mask a String Using Linq Aggregate Method

There are a lot of different ways to mask sensitive data like passwords and account numbers when displaying to users.  Most of them seem to include some sort of loop and/or a regular expression and get the job done. Recently, I wrote a simple function using Linq that I thought was worth sharing.

Here it is:

public static string MaskString(this string stringToMask, string mask, 
 int show)
{
     return stringToMask.ToCharArray().Aggregate("", (maskedString, nextValueToMask) 
          => maskedString + (maskedString.Length < stringToMask.Length - show 
          ? mask : nextValueToMask.ToString()));
}

Explanation:
The function takes in the string being masked, the masking character, and the number of characters to show. It assumes the masking starts on the left and it is written as an extension method.

It’s pretty simple really. The string is converted to an array so the Linq Aggregate function can be used to string the array back together replacing each character along the way with the mask until the show point in the string is reached.

More Info:
The Aggregate function was brought to my attention in a blog post from  By A Tool.  I’ve used variations of this for combining lists of strings and removing duplicates from delimited strings for a system I’ve been working on.  Just for fun I included those below to demonstrate other applications of the aggregate function.

More Aggregate Examples:

public static string CombineListToDelimitedString(this List<String>listOfStrings, 
     string delimiter)
{
 return listOfStrings.Distinct().Aggregate("", (inner, outer) => inner +
         (!inner.Contains(outer.ToString()) ? outer.ToString() + delimiter : "")).TrimEnd( 
 new char[] { Convert.ToChar(delimiter) });
}

public static string RemoveDuplicatesFromDelimitedString(this string delimitedString,
 string delimiter)
{
 return delimitedString.Split(new char[] { Convert.ToChar(delimiter) }).Distinct().Aggregate("", (inner, outer) => inner
         + (!inner.Contains(outer.ToString()) ? outer.ToString() + delimiter : "")     ).TrimEnd(
         new char[] { Convert.ToChar(delimiter) });
}

Conclusion:
Linq never seems to disappoint when looking for a cleaner and cooler looking way of doing things. It just goes to show, there are more than two ways to skin a cat. Or in this case, “mask” a cat.

Yep, that just happened…


Host RESTful WCF(3.5) Service – IIS 6.0 – HTTP 404 – File not found

I ran into this issue today, the fix is  simple and very easy to overlook.  I thought I’d share it.

HTTP Error 404 – File or directory not found.

Internet Information Services (IIS)

I was setting up a WCF REST service on a production server .  The service had been successfully running on two other servers in development and staging.  It runs in the Net 3.5 framework and is hosted in II6 on windows server 2003.

This server has a number of Net applications running , however, it didn’t appear that any websites or web services had been hosted in IIS. So I assumed it was just a setup issue, but setting the website to allow “Directory browsing” served up the directory listing. I began to Google and found a number of posts and articles on the subject.

Other developers reported solving similar issues by running ASPNET_REGIIS, ServiceModelReg.exe, setting up .svc MIME type, and creating a wild card mapping to aspnet_isapi.dll. I discounted the MIME type and wild card mapping since they were not required on our other servers. However, since we’d never hosted a website on this machine let alone a WCF service I decided to run the commands to register ASP.Net applications with IIS and the service modle registration tool. Neither of these solved the issue, so I played with directory security to make sure it matched our other servers, still no luck.

Finally, after a little more research I found that by default in II6 the ASP.net web service extension is set to a status of prohibited for security purposes.  The fix was as simple as opening Web Service Extensions in the IIS manager and setting the ASP.net extension to allowed.

The point is,I focused too much on the specifics of my problem and looked past the basic issue.  Which was that IIS had not been fully setup to host ASP.net applications.  I was “in the weeds” as they say.

Links:
http://msdn.microsoft.com/en-us/library/ms752252.aspx
http://msdn.microsoft.com/en-us/library/k6h9cz8h(v=vs.90).aspx
http://msdn.microsoft.com/en-us/library/ms732012(v=vs.90).aspx
http://www.jamesgoodfellow.com/blog/post/IIS-60—HTTP-404—File-not-found-Internet-Information-Services.aspx
http://support.microsoft.com/kb/248033
http://stackoverflow.com/questions/2009233/how-to-deploy-wcf-service-on-iis-6-0


Someone Is Always Faster – An Older Wiser Runner Knows This

It’s not like I’ve been running around with the illusion that I’m a fast runner, or faster than most, or even faster than many… Maybe faster than some. However, at my best I’m a middle of the pack runner.

During my run today I was reminded of this fact. It was about four  in the afternoon, sunny and in the low sixties. Perfect day for a run.  I was about two or so miles into it, feeling pretty good, I had just started to settle into my run.  Just then, some young guy blew past me, probably running a good minute faster.  To be fair, my day started off at 6am when my youngest got up.  And consisted of laundry, lots of playing with the kids, and cutting the grass. I’m not saying I would of kept up with this guy if I was just starting off my day.  I’m just saying my day had been pretty full and his had mostly likely just started.  Or, I’m just trying to save my ego…

Nevertheless, I stayed on pace and kept myself in my run.  However, it wasn’t so long ago that I would have tried to keep up, or at least would speed up so it wouldn’t look so easy to blow past me.  Just another futile effort to save my ego.   But, if I had, it would have been  to the detriment of my run.

You see,  I was on a six mile run. Which is not a terribly long distance, but for me lately that is a long run.  I’m trying to get my training back on track, it’s been off for probably more than a year now.  The point is, no matter if you’re on a training run or in a race you need to run your run and run your race. If you let somebody else dictate your run and get you off your game, you may not get from your run what you set out to….

Can’t talk about being wise without Yoda!


A Few Of My Favorite Local Races

My last post, The Affect of a Fun Run, was an attempt at making a point on the importance of local fun runs.  As a follow up, I thought I’d list a few I like that are coming up soon.  Starting with the one nearest and dearest to my running heart.

SAILING THRU THE SHORES 5K RUN/WALK (MAY 27)
As I mentioned in my last post this race was the first formal race I ran, since my illustriousness high school track career that is.  It’s a really fun race that takes place prior to the city Memorial Day Parade.  It’s a fast flat out and back.  But, there is a challenging twist.  The race is at noon at the end of May.  This makes for an unusually hot 5k making a personal best unlikely and adding a little challenge to this fun run.  Additionally, the parade goers add a captive audience and an unusually large crowd to cheer the runners on.  The race director, who started the race as part of her reign as Miss St. Clair Shores, has done an excellent job growing the race by adding chip timers and USATF certification in recent years.  Another unique aspect to this race is the cause it supports.  The proceeds are used to provide scholarships for student athelets.

Save The Manatee 5K (May 19)
That’s right, this race has a unique cause,  at least for Michigan.  The race director is a local teacher who organizes this race with her students to raise money for the Save the Manatee Club.  I’ve run this one the last couple years and really like it.  It’s a lot of fun and a great to bring the kids.   It offers several distances so the whole family can get involved and is run inside Metro Beach.  Additionally, it’s really cool to see all the kids out running and volunteering, it’s a real community event.

DODGE PARK 5K RUN (June 2)
It’s been a couple years since I’ve run this one.  But I really liked it the last time I did.  This race is run on the trails inside the park which are a mixture of concrete, dirt, grass, and gravel.  It also has a few small hills.  It’s a nice change of pace from the typical road race.

Run Like a Mother (May 12)
I ran this for first time last year.  This was a fun race which also runs through Metro Beach for part of it.  The event offers shorter distances for the kids, another great family and community event.  The race starts and ends at an apartment building.  Last year they had a great after party.  Complete with almost every option you can think of for post race recovery, live music, hot dogs, free zumba  (no I didn’t).


The Affect of a Fun Run


In my first running blog post I noted that I began running local races about five years ago.  That race was a local 5k in it’s second year(now in it’s sixth) and occurs before the Memorial Day Parade in my town.  It’s a really fun race that I’ve run every year since and plan to run again this year.  Running this race really opened me up to running.  I had so much fun I ran a couple other 5ks that year.  In the years that followed I ran more 5ks, some 10ks, and a couple half marathons.

With this race coming up soon I’ve been reflecting on the affect these types of runs have on our communities and those of us who participate.  Most of these runs are held to benefit a worthy cause.  Anything from fighting cancer or some other horrible disease, to supporting animal rights or local schools.  But, the benefit to the community often goes much deeper then just the charity or cause it supports.  And the impact on the runner can be long lasting, and perhaps life changing.

These races promote healthy living teaching adults and children alike about the benefits of a healthy life style.  In my case, I was already a runner.  But, the previous year when I watched the race I was motivated to give it a try and here I am five years later still running races.  Perhaps in other cases, people who have never run are motivated to run or to start exercising in some way.

Additionally, they provide a way for runners as a community to compete and participate in their sport.  That sense of community  helps to motivate recreational runners to keep running as well as new runners to start.

Finally, because these local runs are usually 5ks and in many cases have a 1mile run it allows runners of any level to participate.


Now I’m a Runner…Or Have I Been?

Running has been a part of my life for a long time.  I’ve been an active runner and running local 5k, 10k, and half marathons  for 5 years.  Prior to that, running was an on and off again part of my exercise routine for at least 10 years.  I even ran track in high school a couple of years, albeit badly.  Yet, for some reason I didn’t consider myself a runner until somewhat recently(last few years).

Even after I began to run local races I didn’t equate myself as a “runner”.  If someone asked, or it came up in conversation, I’d say “I run but I’m not a runner”.  For me, I think I had some idea in my head of what a runner was.   Like I had to be able to run a certain distance or speed.  Maybe I thought I had to look a certain way.  Or perhaps, I worried that other people thought those things and wouldn’t take me seriously if I said I was a runner.

Over time as I ran more races, began reading about running,  and met more runners I found out that this wasn’t the case.  In fact, I learned that running as a sport, recreation, and competition is open to all types of runners.  Those that fit the stereotype and those that don’t.

For me, I found that running is first a competition with oneself.  As such, determining if your’re a runner is really up to you. There is no minimum speed, distance, age, or body weight required.  It doesn’t matter if you’re training for a marathon or running to keep fit.  Being a runner is about running and what you get out of it.  You define it, determine your goals, and enjoy it however you want.

In addition to health benefits some of the things I get from running are community, confidence, pride, and a clear head.

Sure, I don’t run nearly as much as I’d like to right now.  But, I’m thankful for being able to.


Visual Studio Switches

Visual Studio offers a number of command line switches that allow you to run the IDE and perform a specified task.  You can get a complete list and more information here Visual Studio Command Line Switches .

Here are a couple I’ve used.

First /ResetSkipPkgs:

This comes in handy when updating a web reference and get this error: “The components required to enumerate web references are not installed on this computer…”  The error goes on to suggest re-installing visual studio.  But, what this really means is at some point during start up a visual studio extension did threw and error and you said yes to not load it in the future.  All you need to do is run the above command and you should be able to update your web reference.

Second /Log:

Running this will create …\Application Data\Microsoft\VisualStudio\9.0\ActivityLog.xml.  I haven’t used this personally, but the vendor of a third party tool I’m using asked for it to help troubleshoot an issue.  I thought I’d pass it along.


How to Complicate TFS 2010 Upgrade: “TF254006: No usable accounts are present in your configuration database…”

We’re in the process of some long overdue upgrades to our development tools and first up on the list was TFS (2008 to 2010).  This seemed like a simple process.  As a team we’ve had experience installing TFS, build servers, and using VS2008 with TFS 2010.  We did our prep work set a date and off we went (yesterday).  We ran into a few of these:

But after a few hours we were up and running and all was good…

We decided to tackle our automated builds the next day (today) .  That’s when we noticed the configuration tools for the build server had not been installed.  No big deal, or at least it shouldn’t have been.  When we installed the missing component(at the time on the same server) the application tier was removed by mistake…

Again we thought, no big deal, we’ll just re-install them.  And it wasn’t, we re-installed them no problem.  The problem occurred when we ran the “Application Tier” only configuration from the TFS Administration Console.  We got the following error:

It appears that when we upgraded TFS to 2010  the service account was added as the database owner of the Tfs_Configuration database making it the dbo account.  That all worked fine until we had to re-install the application tier.  It would not recognize our service account as the dbo account and allow the connection.  We tried running TFSConfig.exe Accounts /add /AccountType:ApplicationTier /Account:”Service Account” /password:”pwd”  /sqlInstance:”name of server” /databasename:”Tfs_Configuration” to configure the account.

Still no luck.

Finally, we fixed the problem by changing the dbo account for the Tfs_Configuration database to another domain user.  Then explicitly adding our service account to the database.  Once we did that we re ran the  TFSConfig accounts again and TFS is back up running.

Conclusion:

It appears that this issue happens a lot when you’re trying to configure a new application tier over an existing TFS database.  Hopefully, if you run into this your building out a TFS server farm not recovering form a stupid mistake or a disaster.   It’s worth noting that when I was researching this issue I read conflicting information.  Some say running TFSConfig.exe Accounts  was enough while others had to play with database permissions as we did.  In the end, we did both and it worked.  It’s also worth mentioning, after we recovered from the issue we installed the build service on a separate server which is the recommended practice.


%d bloggers like this: