Store Locator - Moved to Codeplex

by Donn Felker 23. November 2008 07:29

image

The Store Locator I built for ASP.NET has been getting a lot of traffic over the last year and requests have been coming in for new features like crazy. To manage this project a little more effectively, I've decided to move the project to CodePlex.

 

You can now download the source from Codeplex here (codeplex.com/storelocator).

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | ASP.NET | GIS

TFS Dependency Replicator Gotcha

by Donn Felker 28. October 2008 03:09

Recently I was working with Dependency Replicator and I ran into an issue.  

 

Background

The file that is the "dependency" does not exist in the destination yet. Therefore the replicator fails. If it does not find the destination file in the dependent project location it will fail. In English: In $/TeamProject/Main/SharedBinaries/ there was no "utility.dll". However, this is EXACTLY where I wanted replicator to PUT the file. Since the file did not exist at the destination, I would receive this error in the event log:

-----------------------------------
Error in Event Viewer:

Dependency Repliccator error:
Event Type: Error
Event Source: DependencyReplicator
Event Category: None
Event ID: 0
Date:  10/23/2008
Time:  11:24:30 AM
User:  N/A
Computer: TFSSERVER
Description:
An error occured processing the dependency '$/TeamProject/Path/To/Dependency/dependency.dll' from build 'TeamProject_CI_20081023.5' in project 'TeamProject'. Processing subsequent rules will continue:
System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\DependencyReplicator\TeamProject\Path\To\Dependency\Dependency.dll'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
   at DependencyReplicator.BuildStoreWatcher.ExecuteDependencyReplicationRule(Rule rule, Workspace workspace)
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

---------------------

 

Steps to recreate:

  1. Create two team projects
    1.   -  One being the one which will propogate the dependency (ex: shared utility dll or something). This would output a file called "utility.dll" which would then
        be propogated to other locations.
    2. Other being the project which utilizes the dependency "MytestProject". DO NOT put the dependency (utility.dll) in this team project anywhere.
  2. Set Depdenency Replicator xml to have the utility.dll file placed somewhere in "MyTestProject".
  3. Kick off a build for the utililty project. This should kick off the dependency repliccator.
  4. Error (above) occurs.

 

Work Around

Place a copy of the "utility.dll" into the destination where the dependency should be. From that point forward you will not have a problem.

 

The Real Fix

The real fix is to fix the source code. Since I'm not a developer on the project I whipped up this code (which please note is only POC at this time).

 

string fullyQualifiedSource = Path.Combine(rule.Event.Data.DropLocation, rule.Source);
string fullyQualifiedDestination = workspace.GetLocalItemForServerItem(rule.Destination);
if(status.NumOperations != 0) 
{
workspace.PendEdit(rule.Destination); 
File.Copy(fullyQualifiedSource, fullyQualifiedDestination, true);
}
else
{
File.Copy(fullyQualifiedSource, fullyQualifiedDestination, true);
workspace.PendAdd(rule.Destination); 
}

I'm going to build this hopefully later this week and submit it to the project. :)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | TFS

How Did C# Get Its Name?

by Donn Felker 28. October 2008 01:23

It's an interesting name to say the least. Why the "sharp" symbol? Sometimes newcomers get it incorrect at first (usually people BRAND NEW to programming) and call it "C POUND". It Almost sounds like a hip-hop thing as the "pound" word has different context in that arena.

The knocking of fists as a form of greeting, departure or respect. - Urban Dictionary

But, alas, this is NOT what it means in terms of programming.

 

Here's Where The Name Came From

In the October 3rd 2008 edition of the CIO article "The A-Z of Programming Languages: C#" Naomi Hamilton interviewed the men of men, the one and only, Anders Hejlsberg (lead architect of C# - and other languages Pre c#). In this article he described where the name came from. The C# language was originally called "Cool" but it was changed. Here's the scoop:

[CIO] Why was the language originally named Cool, and what promoted the change to C#?

[AH] The code name was Cool, which stood for 'C like Object Oriented Language'. We kind of liked that name: all of our files were called .cool and that was kind of cool! We looked seriously at keeping the name for the final product but it was just not feasible from a trademark perspective, as there were way too many cool things out there.

So the naming committee had to get to work and we sort of liked the notion of having an inherent reference to C in there, and a little word play on C++, as you can sort of view the sharp sign as four pluses, so it's C++++. And the musical aspect was interesting too. So C# it was, and I've actually been really happy with that name. It's served us well.

 

Make sense?

csharpOrigins

Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | Misc

Integration Testing

by Donn Felker 24. October 2008 03:03

Integration Testing

gear-bevel Purpose: Testing how the layers/tiers/objects integrate with each other.

When we're unit testing, we're testing a single unit of code. We're testing to see if an addition operation results in what we expect it to.  Does five plus five equal ten? Does this complex calculation f(x) result in y when x = 5? These are the things we're after with unit testing.

With integration testing our goal is to test whether or not our components integrate together. Do they speak (interact) as we would expect?

Example 1: If the "CustomerFacade" (Facade Layer) class interacts with the "CustomerService" (basically, a rules Layer) when we perform the action "CreateNewCustomer", does it work the way we expect it to?

Example 2: If the "CustomerService" (A Service Layer Implementation) must access a remote web service, what is the result? What is the result if the network is down? What is the result if the service is up but is throwing exceptions for every call (perhaps the interface changed). These are integration tests.

A More Refined Definition: At a very basic level integration testing is the combining of two units that have already been tested into a component where the interface between them is tested. In this sense a component is an aggregate of more than one unit. Think of this as two pieces of the application. Perhaps the Customer Facade and the Customer Service. Both handle completely different things (Facade handling the orchestration of the commands, Service handling the execution of a particular command and the order of operations). Each can be tested individually but what happens when we test them together as they are actually going to work within a given system? We now have Integration Testing.

 

Lets look at a quick example with some diagrams to help solidify this concept.

Diagram of System:

 

What We Want to Test: 

image

 

The End Goal of Integration Testing: To identify performance, functional and reliability of the given integration.

 

What we can identify with Integration Tests:

  • Performance/Reliability: If we run 1000 iterations of the same test, does performance degrade? What about 10,000 iterations? What about 100,000? 1M?
  • Incompatibility: The interface between these components may be incorrect. This will usually occur very early in development of the code or in test development.
  • Pattern/Principle Usage: Testing components together can help identify areas in which may need to be refined more. If you realized you're object is doing a price calculation, a customer age verification and a shopping cart total, you may be doing too many things. Look at the Single Responsibility Principle and the Law of Demeter.
  • Component Functional Testing: Are the objects functioning as we have designed them?

 

Example of what we want to test:

In this legacy example we want to test the actual interaction between Legacy and Customer Service. I want to make sure that these two classes work with each other as expected. Our legacy code would look like this:

    public class CustomerFacade
    {
        public void UpdateCustomer(Customer customer)
        {
            CustomerService service = new CustomerService(); 
            service.SaveCustomer(customer);
            
            // Do some other work ... 

        }
    }

We need to re-factor this as we have done in our Unit Testing example. Doing so will turn this class into something  like this:

 

public class CustomerFacade : ICustomerFacade
{
    private ICustomerService customerService;

    public CustomerFacade(ICustomerService customerService)
    {
        this.customerService = customerService;
    }

    public void SaveCustomer(ICustomer customer)
    {
        customerService.SaveCustomer(customer);
        // Do some other work ... 
    }
}

We also need to re-factor the CustomerService class as well...

 

public class CustomerService : ICustomerService
{
    private ICustomerRepository customerRepository;

    public CustomerService(ICustomerRepository customerRepository)
    {
        this.customerRepository = customerRepository;
    }

    public void SaveCustomer(ICustomer customer)
    {
        customer.EditDate = DateTime.Now;
        customerRepository.Update(customer);
    }
}

 

The reason we re-factored this is because the CustomerService object had a dependency on the CustomerRepository. Using the Extract Interface pattern we are able to eliminate the concrete dependency with an interface. We will be able to mock the repository with a mocking framework like Rhino Mocks or TypeMock Isolator.

This is very important: The reason we are going to mock the repository is because we are trying to perform an integration test on the Facade and Service layer. I DO NOT want to test the repository integration. That is ANOHTER INTEGRATION TEST.

Examples of Testing:

In this test we are going to ensure that the CustomerFacade calls the CustomerService which in turn calls the CustomerRepository. If the CustomerRepository does not get called this means that there is something wrong with our integration because CustomerService calls into CustomerRepository. This is what our "integration expectation" is.

 

        
[Test]
public void Customer_Facade_Should_Not_Throw_With_A_Valid_Customer()
{
	MockRepository mockery = new MockRepository();
	ICustomer customer = mockery.Stub<ICustomer>();
	ICustomerRepository repositoryMock = mockery.DynamicMock<ICustomerRepository>(); 
	
	// Lets make sure that the Repository got called. 
	// Review the Fluent Syntax here: http://ayende.com/Wiki/Comparison+of+different+Rhino+Mocks+syntaxes.ashx
	With.Mocks(mockery)
	.Expecting(() => 
	{
		// Lets make sure that repository gets called. 
		// If this DOES get called, the test will succeed. If it does not
		// the test will fail, indicating that our integration test is not working. 
		// Which means we have a problem in how our objects are working together.
		Expect.Call(delegate{repositoryMock.Update(customer);}); 
	})
	.Verify(() =>
	{
		ICustomerService service = new CustomerService(repositoryMock);
		ICustomerFacade facade = new CustomerFacade(service);
		facade.SaveCustomer(customer);
	}); 
}

 

Now lets update the CustomerService class to throw if the customer age is under 18. Now this isn't the best architecture for domain logic, but this is for a simple example. If I were to go down a full Domain design example the details of the test would get lost in the details of the classes.

Here's the new Customer Service:

 

public class CustomerService : ICustomerService
{
    private ICustomerRepository customerRepository;

    public CustomerService(ICustomerRepository customerRepository)
    {
        this.customerRepository = customerRepository;
    }   

    public void SaveCustomer(ICustomer customer)
    {
        if(customer.Age < 18)
        {
            throw new ApplicationException("Only customers over the age of 18 can purchase. Sorry!"); 
        }
        customer.EditDate = DateTime.Now;
        customerRepository.Update(customer);
    }
}

 

Now lets write our test ...  This test should thrown an Application Exception if the customers age is under 18.

 

        
[Test]
public void Customer_Facade_Should_Throw_With_An_InValid_Customer()
{
	MockRepository mockery = new MockRepository();
	ICustomer customer = mockery.Stub<ICustomer>();
	customer.Age = 13;
	ICustomerRepository repositoryMock = mockery.DynamicMock<ICustomerRepository>();

	// Lets make sure that the Repository got called. 
	// Review the Fluent Syntax here: http://ayende.com/Wiki/Comparison+of+different+Rhino+Mocks+syntaxes.ashx
	With.Mocks(mockery)
	.Expecting(() =>
	{
		// Lets make sure that repository DOES NOT get called. 
		// If this DOES get called, the test will fail.  
		// This should never get called because the test should throw before 
		// we get to this point. However, if it does not throw, this will make the test
		// fail. 
		Expect.Call(delegate { repositoryMock.Update(customer); }).Repeat.Never();
	})
	.Verify(() =>
	{
		ICustomerService service = new CustomerService(repositoryMock);
		ICustomerFacade facade = new CustomerFacade(service);
		facade.SaveCustomer(customer);
	});
}

If we get our expected result, we should see an exception thrown. This is what the exception should look like (click for larger):

image

If for some reason the logic in the CustomerService is bypassed, our Expect.Call on the repository should catch the test and fail the test. Here's what happens when this occurs. (Click for larger image)

image

Now that we have our expected integration results - an exception we need to make the test pass. Any time we throw an exception in a class and its expected, we need to add the "ExpectedException" for NUnit. Now our test looks like this:

 

	[ExpectedException(typeof(ApplicationException))]
        public void Customer_Facade_Should_Throw_With_An_InValid_Customer()
        {
            // ... Test stuff (removed for brevity). Its the same as above.
        }

 

Notice the ExpectedException Attribute on top of the method. This informs the unit test framework that we are expecting an exception to be thrown. This is "expected behaviour".

 

Conclusion

We've covered the key differences between Unit Tests and Integration Tests.

Unit Tests - To test an individual unit of code to ensure it is working properly.

Integration Tests - Testing how layers/tier/objects integrate with one another.

Regardless if your doing unit testing or integration testing, its a positive step towards cleaner, more maintainable code. Knowing the difference can help you identify what types of test you have written and types of test you may need to write. Just because you've tested all of your classes at the unit level does not mean that all of them are going to integrate properly. writing integration tests help do this.

Follow the motto: Fail Early. Fail fast.

Unit and Integration tests help do this, very quickly.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | Testing

Twin Cities Code Camp This Weekend

by Donn Felker 7. October 2008 01:47

Just a reminder for all of you in the Twin Cities Area (Minneapolis/St. Paul) ... Twin Cities Code Camp will be this weekend!

I will be speaking - the presentation is entitled: Smooth Operator: Using the Workflow Rules Engine Within WCF

See you then...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | Events | WCF

.NET 4.0 and Visual Studio 2010

by Donn Felker 7. October 2008 01:35

Sometimes it feels like you've been hit by a car, sometimes it feels like a freight train. Either way, if you're in this industry and you're not ready for change or if you're not crazy enough to "know  you can figure it out" then its time to get out...

Why?

.NET 4.0 and Visual Studio 2010 are already on their way.

 

I haven't even upgrade to 2008 yet...

I know, and neither has the rest of the world. This is possibly one (of many) instance where companies might just skip 2008 and go to 2010 because of the release cycles. At this point they're getting so close that its impossible to keep up. A colleague I was working with and I were talking about how Redhat suffered from this same rapid release cycle. Back in the days before Redhat slowed its releases down you would see a new Redhat OS released every couple of quarters. No business in their right mind would keep up with a release schedule that could possibly introduce problems with system integrity.

 

New Things Coming to .NET 4.0 and / VS 2010

The real big thing here is: ALM (Application Lifecycle Management)

You have the:

  • Architecture Explorer
  • Design Diagrams (we already have some of these but more are to come)
  • Better collection of test data
  • Test Impact View: Run tests that are affected by a code change. This is huge, so instead of running your 1000 unit tests to make sure your change didnt affect anything (which you should still do IMO anyway) the big blue is telling you to "just run what's changed". Some instances are very difficult to test, especially when using reflection or if you're using string literals to build things (which is bad anyway ... more on this at a later time).
  • Gated Check in - Makes sure that the code passes a # of tests prior to the code being committed to the system. Similar to Open Gauntlet.
  • Branch Visualization - This is super nice. Be able to see how and what your branches are touching and/or connected to. Screencast here.
  • Build Workflow - I'm not really sure what this is going to do but my guess is that it will allow you to identify build steps in order to successfully build things. Hopefully streamlining the MSBuild process a bit more.
  • More modeling - In my opinion this is more Oslo related stuff. More modeling from a higher level to let your architects see what's "really" happening. However, this is very subjective at this point ... more on this later.
  • Eliminating the "no-repo" bugs. Again... this is completely subjective. I'm afraid this is not possible... how can you possibly remove the no-repo bugs? You cant. There will ALWAYS be a time when a bug occurs in a certain instance with a certain config that is darn near impossible to repo.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

4 Common Follies Made In Unit/Integration Testing

by Donn Felker 3. October 2008 09:19

I was having a discussion with a colleague last week and we got on the topic of unit testing. What unfolded is what stemmed this post... It started like this...

Colleague: "There is no need to test getter's and setter's in a property, because 'I know they work'."

Me: "WHOA WHOA WHOA!! You know they work? How? Please inform me, because I KNOW my code works too, but I also know I MAKE MISTAKES, A LOT OF STUPID MISTAKES... "

The conversation continued and eventually spawned this post ... but before we get started, I'd first like to say I've been burned by all four of these follies, so I know first hand how important they are.

  1. Not Testing Components
  2. Using a shared database
  3. Testing code that depends on external objects
  4. Writing a test stub and not finishing the test

 

1. Not Testing Components

"I don't need to test that, I know they work." - you, me, everyone (at one point in time) :)  

Why its a Folly: A few questions in regards to this should set us up nicely ... Why are you even trying to perform testing of any kind if you're not testing even the basic stuff? This is the REAL SIMPLE stuff that should not be ignored. Seriously, If you write code and you KNOW its solid, then why write tests for it if your so confident? Think about that... That doesn't make sense! WE'RE ALL HUMAN, WE ALL MAKE MISTAKES. That's why. No one's code is perfect. I don't care who you are. Also, what happens after you check in your code and then tomorrow Developer X checks out the code, makes a change to a setter and then checks it back in. How do you know if that did or did not break anything? YOU DON'T.

Example:

Your original code - a simple read only property that returns the order total:

public double OrderTotal { get; } 

 

Developer X's code after he changed it. He added the new "customer level pricing discount" feature that was requested by your boss.

private double orderTotal; 
public double  OrderTotal 
{ 
	get 
	{ 
		if(customerLevel == CustomerLevel.Platinum)
		{ 
			orderTotal = TotalOrderAfterCustomerDiscountAppliedFor(customerLevel); 
		}
		return orderTotal; 
	} 
}

 

Unfortunately, because no test was written to act as a parachute to catch us (to make us fail early) we are now possibly introducing a bug into the system. Also we have no unit test backing up the new business functionality. Unfortunately because "you know it works" doesn't cut it in this case. The QAT team fires up the app and notices the system has some "odd behavior" at certain times of execution. A bug is submitted and you eventually trace down the source of the error to the property accessor change. Oops.

 

What To Do: Test your properties. Its easy, its quick and it will save your *ss in a bind. Trust me, I've been that guy that said "I know this works, its part of the framework." . If you want to make life real easy on yourself you can even set up a ReSharper Template for it. Its not that hard.

 

Notes: For example - I'm not saying to go out and test that the FileInfo class actually does what it says. If your code or the framework offer the ability for a bug to exist, then test for it. Regarless if its there OR NOT. It's your parachute. You don't see skydivers skimping out on their equipment do you? They do have an EMERGENCY pack. Yeah, THEY KNOW their main pack works. But what if it doesn't? We all need a back up plan to help us out.

 

 

2. Using a  Shared Database

At times you will NEED to connect to a database to perform some type of integration testing.

 

Why its a Folly: Most teams that I've worked have begun working from a shared "dev" database. This introduces so many problems with the dev workflow environment that only an example is the best way to describe the madness going on here.

It usually goes like this (you've probably seen this before too):

  • DevA updates a SprocX on the Dev DB server
    • Changes are validated by "running the app"
  • DevB updates a table definition on the Dev DB Server
    • Changes are validated by "running the app"
  • DevA develops some new functionality, runs app to debug and then it breaks on some code that he DID NOT CHANGE.
    • He gets a SQL Exception stating that column "CustomerNo" is not found in SprocX.
      • What? Huh? I just validated this 20 minutes ago. WTF?!
      • He looks at the code, talks to his peers, finds out that DevB had to make a change for Feature123 that made him change the column name to "CustomerNumber".

It's complete madness working with a shared model. DB Objects get overwritten, changed, updated, you name it - it WILL HAPPEN. Murphy loves to come visit during this time. The amount of un-managed change is too much to handle for any team. Following a shared model usually creates far too much friction for any team to succeed in any time boxed environment (and who doesn't live in one of those).

 

What To Do: Implement a Database Sandbox for each developer. In this example we provide a separate development or test database for each developer.

Note: Managing changes in a database is a challenging task all in itself. This can be intensified in any multi-developer environment. Read K. Scott Allen's series on version control for a database.

  1. Three Rules for database work (note the first bolded topic in this post... )
  2. The Baseline
  3. Change Scripts
  4. Views, Stored Procedures and the like
  5. Branching and Merging

 

 

3. Testing Code that depends on external objects (network, file, web service)

Continuing with the previous item, when writing unit tests that depend on an external service (in this case - a database) states that you are making the following assumptions: 

  1. The Network is up and working
  2. The remote machine your connecting to up and running
  3. The database server is running
  4. The database server is accepting remote connections
  5. The database in question is ACTUALLY ON THAT SERVER
  6. The connection string is correct
  7. No one has messed with what you're about to test
  8. and ... the planets align correctly

We're assuming that the database is in the correct state. What if this is a shared environment? What  if someone changed something? What if the network hiccups? Trust me, if it can happen, it will happen. I know first hand because all of this has happened to me.

 

Why this is a folly: Again, you're betting on the fact that 1-7 above (if not more) are going to succeed. What if this is a web service? What types of things are you betting on there?

  1. The network is up
  2. The the Internet connection is up
  3. The remote server is up
  4. The web service address is correct
  5. The web service interface has not changed
  6. The web service in face does what you expect it to do
  7. blah, blah, blah - too much!

The same follies again! A file is no different. Heck, even another class can be this way. Imagine working with a class that requires HttpContext to be available? It would be a mess to try to reconstruct this object graph to ensure that my test result was the same.

 

What To Do: This is a lot harder than it sounds - break your dependencies. Testing is not the only thing you'll get from this. You'll get flexibility, functionality and the ability to become more agile with your software. How do you break your dependencies... implement some dependency injection techniques into your code. After you break these dependencies you can mock them out with fake implementations to streamline your testing.

 

4. Writing a Test Stub & Not Finishing The Test

I'll leave the easy one for last... this one is easy to fix. :)

Ok, I'll be the first to admit, I'm guilty of this from time to time. However, I have become older and wiser and I have now started implementing an initial not implemented exception throw upon the test getting created.

Here's what I'm talking about when we forget (this test will pass):

[Test]
public void Customer_must_be_21_to_drink_booze()
{
	ICustomer customer = new Customer("FirstName", "LastName"); 
	// TODO: Finish Test. Ran out of time this afternoon! :) 
}

 

Why this is a folly: Its not a completed test. It does not do anything.

 

What to do: Here is what I do to eliminate this (this test will fail):

[Test]
public void Customer_must_be_21_to_drink_booze()
{
	throw new NotImplementedException(); 
}

 

 

 

Conclusion

We all make mistakes, I hope that this post helps at least a few people NOT make these mistakes. :)

Currently rated 4.7 by 3 people

  • Currently 4.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | TDD | Testing

RuleSetDialog & LINQ Queries

by Donn Felker 2. October 2008 06:11

I'm working on a presentation for the Twin Cities Code Camp and I've upgraded some old samples that Microsoft provided for the new version of .NET 3.5. Upon doing so I imagined the question coming up during the presentation "Well, can we use LINQ in the rule set editor"? Good question.

 

And here's the simple answer: NO.

 

Check it out - this it the validation error from the RuleSetDialog editor.

 

image

 

In my opinion the editor should allow this, but alas it doesn't as this would be rather difficult to represent in the serialized RuleSet file. This might be an issue with the form supporting code definitions in the conditional window, which is probably a whole new bunch of problems.

 

I have also looked to extend the form but this does not look possible and from a few forum posts I've read Microsoft does not want you extending this control. Bummer man.

 

Hacky Fix

Place all of your LINQ code style items in Properties or methods that you can then access from the Condition window. Not a superb answer, but it works in a bind.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

That Sneaky .NET 3.5 External RuleSet Toolkit Sample

by Donn Felker 30. September 2008 08:07

This is a quick note to those of you who are trying to access the External RuleSet Toolkit Sample in this download on MSDN.

The .NET 3.5 External RuleSet Toolkit sample is a Workflow Rules Engine Sample that shows you how to externalize the Workflow's Rule engine for your own evil, errr, I mean good.

 

Sneaky Sneaky

Well, let me in on a little secret.... The sample is... sort of... well... hidden from you.

Its not in the WF samples, its in the WCF samples. Seriously, WTF?

Check it out:

image

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Custom Google Maps Geocode Powershell CmdLet

by Donn Felker 18. September 2008 09:43

This may look like a repeat... well.. because it is... BUT.. you cannot find the old post. Why? Because, well ... it no longer exists. My old host decided to accidentally delete my account. Yeah. Oops. After that nightmare, I've moved to a new host where the grass is greener, the hippies wear deodorant and well ... wait ... never mind... onto the good stuff...Here's the old post, reposted again.

---------------------------------

Ok, I admit ... I have a fascination with maps. Why? Who knows. I just love knowing where I'm at, where I'm going, not being lost, etc etc etc. Last year I wrote a C# class that would connect to Google Maps and return the latitude and longitude of an address by utilizing the Google Maps API. Get that class

Awhile back I also wrote about the complexity of our industry and about how staying up to speed is quite difficult. Jeffrey Snover (PowerShel/Windows Management Architect) commented on that post and recommend learning PowerShell. I completely agree with what he said. However - I've only scratched the surface of PowerShell and its capabilities and just recently I picked up a copy of Bruce Payettes "Windows PowerShell in Action". So far, its a great book. I'll post a review when I'm done. But as I was reading I got into thinking about how I would like to Geocode addresses from the command line in certain instances. A custom PowerShell cmdlet was in fashion. 

 

The Get-GoogleGeocode CmdLet

At that point, the Get-GoogleGeocode cmdlet was born. I took my code from the C# Google Maps Geocoding class I wrote, added a new property "Address" (which is what I needed to store the address the user supplied) as a simple string and then wrapped it in a cmdlet. 

The result? An awesome cmdlet. 

The cmdlet will take your Google Maps API Key and a list of addresses and it will Geocode them for you. Very simple, yet very powerful. 

Lets take a look at what it can do: 

Examples

 

Note: My Google Maps API key has been hidden in the examples below ... SO YOU DONT STEAL IT! ;)

 

Script Explanation

Click the pictures for full resolution images.

 

 

Example 1:  Gets  the longitude and latitude for one single address and outputs it to the screen.

ps1

PS C:\Development\DF.PowerShell.Cmdlets\bin\Release> Get-GoogleGeocode -apiKey <YourAPIKeyGoesHere> -addresses "2203 E. Empire St. Bloomington, IL 61704"

Address Latitude Longitude
------- -------- ---------
2203 E. Empire St. Bloomington, IL 6... 40.488283 -88.945315

 

Example 2:  Gets the longitude and latitude for multiple addresses and outputs them to the screen. 

ps2

PS C:\Development\DF.PowerShell.Cmdlets\bin\Release> Get-GoogleGeocode -apiKey <YourAPIKeyGoesHere> -addresses "2203 E. Empire St. Bloomington, IL 61704", "8300 Norman Center Dr., Suite 950 Bloomington, MN 55437"

Address Latitude Longitude
------- -------- ---------
2203 E. Empire St. Bloomington, IL 6... 40.488283 -88.945315
8300 Norman Center Dr., Suite 950 Bl... 44.853079 -93.352194

 

Example 3:  (I think this is the REALLY cool one) Opens a file, reads each line and gets the longitude and latitude for each address in the file.

ps3

PS C:\Development\DF.PowerShell.Cmdlets\bin\Release> Get-Content c:\temp\MicrosoftOffices.txt | Foreach-Object {Get-Goog
leGeocode -apikey <YourAPIKeyGoesHere> -addresses $_ }

Address Latitude Longitude
------- -------- ---------
2203 E. Empire St. Bloomington, IL 6... 40.488283 -88.945315
77 W. Wacker Dr., Suite 2300 Chicago... 41.886499 -87.630526
3025 Highland Pkwy., Suite 300 Downe... 41.831445 -88.010731
500 E. 96th St., Suite 460 Indianapo... 39.928171 -86.150754
N19 W24133 Riverwood Dr., Suite 150 ... 43.056940 -88.229463
4601 Westtown Parkway, Suite 136 Wes... 41.610376 -93.711712
10801 Mastin Blvd., Suite 620 Overla... 38.932978 -94.702328
8300 Norman Center Dr., Suite 950 Bl... 44.853079 -93.352194
3 City Place Dr., Suite 1100 St. Lou... 38.670381 -90.433552
13815 FNB Parkway Omaha NE 68154 41.266103 -96.130733

 

Script HELP

If you ever forget about how to run this command, I have included the help files as well. 

Access help by typing: Get-Help Get-GoogleGeocode. This will give you very basic help. For detailed or full help type: Get-Help Get-GoogleGeocode -detailed or  Get-Help Get-GoogleGeocode -full

To use this script, execute the command Get-GoogleGeocode and supply a api key and a list of addresses separated by a comma. 

From help:

PS C:\Development\DF.PowerShell.Cmdlets\bin\Release> get-help get-googlegeocode
NAME
    Get-GoogleGeocode
SYNOPSIS
    This cmdlet will return the latitude and longitude of the addresses that are passed into the cmdlet.
SYNTAX
    Get-GoogleGeocode -ApiKey <String> -Addresses <String[]> [<CommonParameters>]
DETAILED DESCRIPTION
    This cmdlet will return the latitude and longitude of the addresses that are passed into the cmdlet. The apikey is
    required for this to work. Also, you may encounter proxy issues if you require a proxy for access to the internet.
    This cmdlet utilizes the System.Net.WebClient class to access the internet. This cmdlet will connect with the Googl
    e Maps API, ask for the geocoding information and then return it.
    You will need a Google Maps API Key for this. Sign up for one here: http://code.google.com/apis/maps/
    If the latitude and longitude are both ZEROS, this means the address could not be geocoded.
RELATED LINKS
REMARKS
    For more information, type: "get-help Get-GoogleGeocode -detailed".
    For technical information, type: "get-help Get-GoogleGeocode -full".

 

How to Install

Start powershell and navigate to the Release directory run the "install.ps1" script from the command line. It should look like this when you run it: 

install

 

How to uninstall?

Run the uninstall.ps1 script. Running that script should result in something that resembles this:  

uninstall

 

Downloads

C# Solution & Binaries: DF.PowerShell.zip (44.51 kb)

Note: Text File with Addresses from Example 3 is included in solution download.


Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | PowerShell

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About the author

Donn Felker

Senior Consultant
MCTS
ScrumMaster
Agile Practitioner

About Me | Books I Recommend

Gotta Pay The Bills


Tag cloud

    Popular Posts

    RecentComments

    Comment RSS

    Calendar

    <<  December 2008  >>
    MoTuWeThFrSaSu
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    View posts in large calendar