Hi, folks! In this post I will cover some subjects about Software Architecture, the SOLID design pattern (and why it was used), dependency injection with Unity and ASP.NET MVC. I came up with this, because I was having trouble with a geo location service I always used in this website to provide weather information.
I won't write pages and pages about SOLID, you have a variety of online material, but if you are reading this without a basic knowledge about system interfaces (not front-end interfaces) you are gonna have a bad time...
Why SOLID and Dependency Injection?
Ok, before you decide to apply the design pattern, meaning TIME is going to be invested while doing so, you need to understand it. To make it simple, SOLID is not for implementing only because it seems cool.
In order to make adaptive code a reality and in this case, the flexibility of using different geolocation provider APIs, I needed to design a middle layer between the website and them (providers). You can get an idea from the following pictures:
If the service provider failed (or the website exceeded its calling quota), the whole weather information thing would not work. By using Unity and the stuff, although there's a drawback of additional work and tweaks, I can use different services or even instances from different providers, making it more difficult to fail the process at this step.
The subject is a good example for this story, because calling geolocation APIs are relatively simple: they don't hold states, meaning I wouldn't have to plan and predict this behaviour at my side of the middle layer.
Why should I have to build a middle layer (with c# interfaces, models and so on)?
Yeah, if you had this question, you still don't understand SOLID and Unity with MVC. In order to use anything, any third-party code, the C# platform needs a definition. And through c# interfaces and dedicated class models, you create that definition.
The said middle layer is important in this case, because it's meant to provide a common definition over several geolocation providers. So the application can use 2, 3 or even more providers under the same definition of a middle layer.
One good example for this is the ADO.NET itself: it is composed by a series of common classes and interfaces, so database providers can implement their code based on it and we can use them without having to change our code a lot. We can use Oracle databases, SQL Servers databases at the same time and the application doesn't even have to know about those details (you get it now, don't you?)
Let's get started!
First, git clone the repository for this post at this link. You can see an interface called ILocationService, which it's our main character, and two classes inside 'Concrete': FreeGeoIp and IpInfoDb.
They will be our providers for geolocation and they work differently: the first doesn't require registration, but has a limit of up to 10000 queries an hour. The second requires registration, doesn't have an 'up' limit at all, but limits how many calls can be made during a period of time.
If you want to use IpInfoDb, you must go to their website, register yourself and use the API key provided by them. And you can use more than 1 API key inside your application, increasing the reliability on the location feature.
Adding instances of ILocationService to the Unity Container
Open the solution and go for the UnityConfig.cs file inside App_Start of the web application. If you take a look at the RegisterTypes method, you will see 3 instances being registered in the name of ILocationService: one for FreeGeoIP and 2 for IPInfoDB. If you had registered at least one API key for yourself, you can uncomment the lines for IpInfoDb service.
Now, find the HomeController and go for its constructor. You will see an instance of ILocationService being found (with a bunch of rules to do so) from the container. It's basically looking for an instance of a service that isn't maxed out, so it can be called and also looking for the least called one (kind of a scatchy load-balance).
Now, run the application and click on "Find your Location" upper menu. You can breakpoint the HomeController, the concrete types FreeGeoIp and IpInfoDb to see how's everything working!
Later on, you can find other providers online, implement it according to Services.IpLocation middle layer, register any instances on your UnityContainer and you will have another option for finding someone's location based on their IP.
There's even free IP databases online, so instead of relying purely on HTTP APIs, you can use a database without having impacts on your code!
Hope you guys enjoyed it. See ya!