The first question to ask yourself is what is GeoData? In other words, what is the class's responsibility?
It appears to be part of the Domain Layer, and as such might contain business logic. It may be used by (coupled to) other classes.
If that's the case, what are the dependencies? One way of determining this is by attempting to write unit tests that test GeoData in isolation. If testing requires significant setup, the class under test is either tightly coupled to other classes or has multiple responsibilities (low cohesion).
Let's say we change the class so that the constructor takes a connection string parameter. How can we test the public GetCountries method? Well, first we set up a database with known test data...
That's time-consuming and fragile (what if someone updates the data?), and the test will run relatively slowly (it has to connect to the database).
Well, we could pass in an object implementing IDbConnection to the constructor (constructor injection). Note that dependency injection normally involves passing in interfaces or abstract classes. To test it, we'd have to create a fake IDbConnection. We could use an isolation (mocking) framework. But then we'd need it to create a fake IDbCommand when CreateCommand was called...
To quote Jeremy Miller (author of StructureMap) "It’s too much effort for too little gain." See his article Best and Worst Practices for Mock Objects.
One possibility is to use the Repository Pattern. You would pass in an interface to the specific repository to the GeoData constructor. This would be easy to fake (manually or with a mocking library) for testing. The concrete repository would handle all the data access. It could be combined with an ORM framework to further abstract the data access. Connection string management would be done through the ORM or through the repository (preferably in another dependency or a base class).
If this sounds complex it's because it is. You picked one of the most difficult cases for Dependency Injection (which, unfortunately, is also one of the most common).
Dependency Injection by itself is a fairly simple concept. If your class is calling a Web Service, you can place the Web Service code in a separate class that does nothing else, implement an interface, and pass that interface to your original class. DI/IoC container frameworks can make this easier to do if you have a lot of classes and/or dependencies, but they aren't a requirement.
EDIT: Just to be clear, Dependency Injection is not the complex part. Separating the data access is.