Hi, folks! In this post I will show you how to use Unity and Dependency Injection to provide/retrieve weather information for your website. Last time I talked about it, I covered the subject IP Geo Location in an MVC application under the same idea.
This website uses the same code to provide weather and forecast information in some sort of a widget.
Reading about SOLID, a design pattern that relies heavily on system interfaces and dependency injections, I usually found that the given examples are not so good to understand the subject. IP-based geolocation providers (through the use of their HTTP APIs, of course) are a good one, because their workflow is very simple: you need to identify the real location given an IP.
When it comes to weather information and different providers, things start to get complicated: their output differs a lot, the features they offer also differ and we have two options: temperatures in degrees fahrenheit and celsius. For example, Forecast.IO provides all information needed at one shot (current temps and forecast), while OpenWeatherMap offers an endpoint for current temps and another for the forecast (in other words, 2 calls to obtain the whole weather + forecast information from providers that limit the number of calls to them).
But the most important: the visual representation of the weather (the icon that represents the weather) also differs between them. Not a lot though, because we are talking about weather, but enough to demand our code interpretation.
The middle layer
In order to make SOLID happen, we will build another middle layer for the weather part of the application. Although there will be a reference between the MVC app and the weather module, the controller classes should only use models and touch abstract definitions from whatever provider we are using (either geolocation or weather).
In other words, we have FreeGeoIp, OpenWeatherMap and ForecastIO concrete classes. They should not be used directly in your front-end code or it won't be worth.
Think of it as a cheeseburger: the top bun is the website, the hamburger is the middle layer with unity and dependency injections and the bottom bun is the weather service providers.
Please note that the top bun should not touch the bottom bun or else it won't be a freaking burger. lol
Let's get started!
First, git clone the repository for this post at this link and open the solution inside your Visual Studio 2015. Browse to UnityConfig.cs, inside the App_Start folder of the Website.MVC application. In the method RegisterTypes, you will see 2 instances of IWeatherService being registered in the container:
The container provides all the service instances we need and have available inside the solution.
So, before running the application, you will need to register with these providers and use the API keys they'll provide you. Or else the application won't function properly. Once that's done, paste them in place of "YOUR API KEY" string values and push the PLAY button.
FreeGeoIp IP GeoLocation doesn't require registration, you can use it right away.
When you start interacting with the page, it's basically getting information step-by-step from an APIController called WeatherController.cs. Yeah, the sample app is using Web API 2! I will now explain what's going on with some methods of it.
Taking a look at the UserLocation method, the app is basically inquiring the unity container for a geolocation provide (through the system interface ILocationService). It truly doesn't matter which one we have registered inside the container, as long as it's still valid to be called.
Now, find a method called WeatherInformation. As you can see, the same situation is happening there: the app inquires the container for a weather provider (through the definition of the system interface IWeatherService). Again, because of the work done with the middle layer, although we clearly have some differences between Forecast.IO and OpenWeatherMap.org HTTP APIs, we can safely use both of them for either current temperatures or forecast prediction.
And that's the magic behind SOLID design pattern: once we implement services under a definition of the middle layer, we can use multiple instances of any provider and the application stays unmodified. So, let's say one of the providers stops working for no reason whatsoever: all we need to do is comment the corresponding lines inside UnityConfig.RegisterTypes method and/or adding more instances from a reliable provider, with more API keys.
I hope you guys enjoyed! See ya.