What if you could have an application that provides multi-layer solutions for numerous support and self-help needs? An application that, on one hand, provides silent fixes, notifications about detected issues, and self-help wizards, while on the other hand keeps a low profile with minimal impact on the client and the customers? And what if that same application is actually a development framework that enables IT developers to add new tools or system checks easily and quickly? What if it can be managed from a centralized location and silently updated with content or new components? And finally, what if it can operate autonomously even when the computer is not connected to the enterprise network? It may sound as if we are asking for too much, but this is exactly what Intel IT created during the past year, with a small team of developers. We call it the Virtual Assistance Center (VAC), and it is described in our recent white paper, “Virtual Assistance Center Advances IT Self-Service.”
The compute environment at Intel is constantly changing, with new or different hardware, applications, and employee customizations. This state of flux means that new problems often arise, and therefore new fixes are required, and additional information may need to be added to the self-help tasks that IT provides.
As a development platform, the VAC promotes IT innovation, encouraging IT employees to act on new ideas and implement new fixes. It could be a self-help idea or a proactive monitoring idea, but what is important is that IT application developers like me are not dissuaded from implementing something new by difficult, drawn-out development and testing processes. The VAC framework enables developers to deploy something new in just a few days or maybe a couple weeks—compared to months prior to its creation.
In this blog post, we share some of the techniques we used during the development that helped us achieve such results with limited resources and time. We didn’t invent these techniques—we’re just using standard stuff to create something better.
Inversion of Control and Dependency Injection
I don’t want this blog to become a tutorial on new approaches to object-oriented programming. But I think it is important to explain at a high level how we use inversion of control (IoC) and dependency injection (DI) to increase the flexibility of our development framework.
IoC is an approach to programming that decouples the “what-to-do” from the “when-to-do-it.” (You can find more discussion about IoC in many places; two of note are an interesting conversation and Wikipedia’s coverage.)
Numerous sources use the terms IoC and DI interchangeably, but they are not the same. Actually, DI is just one type of IoC. In simple words (and illustrated by the following diagram), when you are using DI you are implementing IoC by injecting dependencies, allowing the calling function to provide your class with all the components (instances) it needs, without actually instantiating them inside the class. There are numerous advantages to this design pattern, the primary one being that you are able to test discrete units of code. Additional advantages include being able to replace components without breaking the code and superior encapsulation. An extra advantage that we discovered during our work was the ability to decouple one developer’s work from another’s. No longer does one developer need to wait for another one just because he or she needs some component to be completed or fixed. Instead, a simple “mock and inject” technique allows developers to work independently until the very last moment of integration. This point was one of the success factors for VAC.
While the DI design pattern is relatively easy to grasp, the implementation can be a bit tricky. That is why there are so many various IoC/DI containers available for every programming language and development platform. We used one of those containers in order to cover all our IoC needs.
Complex tasks can sometimes require more complex tools. The DI design pattern covered most of our needs for the structure of the development platform, but in order to make it really flexible and to allow IT developers easy access to internal platform APIs, we decided to use “an antipattern.”
The service locator pattern (also a type of IoC) is considered by many to be an antipattern. It allows code to request any instance of any object anywhere! It is a powerful tool, but using it can lead to chaotic code, arguably worse than using GOTO statements. Using the service locator pattern, we were able to create a provider object that can be injected by the container into dynamic tasks and provide developers with access to various local and external data sources, only instantiating the ones that are needed.
We used numerous other patterns and techniques during the development of the VAC, such as a technique for self-update, and managing various user groups for gradual deployment and field testing. These will be topics for some future blog posts.
Intel IT developers are excited about the VAC and its underlying development framework. As one of my colleagues put it, “VAC gave us a toolset, we just need to get the logic right, and that is it. This is great!” It is not uncommon now for several new fixes to be developed every week. Therefore, we have implemented continuous integration, where the VAC receives updates every couple of minutes.
I hope that the information in our white paper and this blog inspires other IT departments to develop something similar. We have found the benefits—including better IT products, more productive employees, and a better user experience for both developers and employees—to be well worth the effort it took to implement the VAC. I encourage you to share your relevant thoughts and experiences by leaving a comment below.