Archive for the ‘Ioc’ Category

CouplingDesignPatterns

Author: Cole Francis, Architect

BACKGROUND PROBLEM

My last editorial focused on building out a small application using a simple Service Locator Pattern, which exposed a number of cons whenever the pattern is used in isolation. As you might recall, one of the biggest problems that developers and architects have with this pattern is the way that service object dependencies are created and then inconspicuously hidden from their callers inside the service object register of the Service Locator Class. This behavior can result in a solution that successfully compiles at build-time but then inexplicably crashes at runtime, often offering no insight into what went wrong.

THE REAL PROBLEM

I think it’s fair to say that when some developers think about design patterns they don’t always consider the possibility of combining one design pattern with another in order to create a more extensible and robust framework. The reason why opportunities like these are overlooked is because the potential for a pattern’s extensibility isn’t always obvious to its implementer.

For this very reason, I think it’s important to demonstrate how certain design patterns can be coupled together to create some very malleable application frameworks, and to prove my point I took the Service Locator Pattern I covered in my previous editorial and combined it with a very basic Factory Pattern.

Combining these two design patterns provides us with the ability to clearly separate the “what to do” from the “when to do it” concerns. It also offers build-time type checking and the ability to test each layer of the application using an object’s interface. Enough chit-chat. Let’s get on with the demo!

THE SOLUTION

Suppose we are a selective automobile manufacturer and offer two well-branded models:

    (1) A luxury model named “The Drifter”.
    (2) A sport luxury model named “The Showdown”.

To keep things simple, I’ve included very few parts for each make’s model. So, while each model is equipped with its own engine and emblem, both models share the same high-end stereo package and high-performance tires. Shown below is a snapshot of the ServiceLocator Class, which looks nearly identical to the one I included in my last editorial. For this reason, I’m not color-coding anything inside the class except where I’ve made changes to it. I’ve also kept the color-coding consistent throughout the rest of the code examples in order to depict how the different classes and design patterns get tied together:


namespace FactoryPatternExample
{
    public class ServiceLocator
    {
        #region Member Variables

        ///
        /// An early loaded dictionary object acting as a memory map for each interface's concrete type
        /// 
        private IDictionary<object, object> services;

        #endregion

        #region IServiceLocator Methods

        ///
        /// Resolves the concrete service type using a passed in interface
        /// 
        public T Resolve<T>()
        {
            try
            {
                return (T)services[typeof(T)];
            }
            catch (KeyNotFoundException)
            {
                throw new ApplicationException("The requested service is not registered");
            }
        }

        /// 
        /// Extends the service locator capabilities by allowing an interface and concrete type to 
        /// be passed in for registration (e.g. if you wrap the assembly and wish to extend the 
        /// service locator to new types added to the extended project)
        /// 
        public void Register<T>(object resolver)
        {
            try
            {
                this.services[typeof(T)] = resolver;
            }
            catch (Exception)
            {

                throw;
            }
        }

        #endregion

        #region Constructor(s)

        ///
        /// The service locator constructor, which resolves a supplied interface with its corresponding concrete type
        /// 
        public ServiceLocator()
        {
            services = new Dictionary<object, object>();

            // Registers the service in the locator
            this.services.Add(typeof(IDrifter_LuxuryVehicle), new Drifter_LuxuryVehicle());
            this.services.Add(typeof(IShowdown_SportVehicle), new Showdown_SportVehicle());
        }

        #endregion
    }
}


Where the abovementioned code differs from a basic Service Locator implementation is when we add our vehicles to the service register’s Dictionary object in the ServiceLocator() Class Constructor. When this occurs, the following parts are registered using a Factory Pattern that gets invoked in the Constructor of the shared Vehicle() Base Class (highlighted in yellow, below):


 
namespace FactoryPatternExample.Vehicles.Models
{
    public class Drifter_LuxuryVehicle : Vehicle, IDrifter_LuxuryVehicle
    {
        /// 
        /// Factory Pattern for the luxury vehicle line of automobiles
        /// 
        /// 
        public override void CreateVehicle()
        {
            Parts.Add(new Parts.Emblems.SilverEmblem());
            Parts.Add(new Parts.Engines._350_LS());
            Parts.Add(new Parts.Stereos.HighEnd_X009());
            Parts.Add(new Parts.Tires.HighPerformancePlus());
        }
    }
}



 
namespace FactoryPatternExample.Vehicles.Models
{
    public class Showdown_SportVehicle : Vehicle, IShowdown_SportVehicle
    {
        /// 
        /// Factory Pattern for the luxury vehicle line of automobiles
        /// 
        /// 
        public override void CreateVehicle()
        {
            Parts.Add(new Parts.Emblems.GoldEmblem());
            Parts.Add(new Parts.Engines._777_ProSeries());
            Parts.Add(new Parts.Stereos.HighEnd_X009());
            Parts.Add(new Parts.Tires.HighPerformancePlus());
        }
    }
}


As you can see from the code above, both subtype classes inherit from the Vehicle() Base Class, but each subtype implements its own distinctive interface (e.g. IDrifter_LuxuryVehicle and IShowdown_SportVehicle). Forcing each subclass to implement its own unique interface is what ultimately allows a calling application to distinguish one vehicle type from another.

Additionally, it’s the Vehicle() Base Class that calls the CreateVehicle() Method inside its Constructor. But, because the CreateVehicle() Method in the Vehicle() Base Class is overridden by each subtype, each subtype is given the ability to add its own set of exclusive parts to the list of parts in the base class. As you can see, I’ve hardcoded all of the parts in my example out of convenience, but they can originate just as easily from a data backing store.



namespace FactoryPatternExample.Vehicles
{
    public abstract class Vehicle : IVehicle
    {
        List _parts = new List();

        public Vehicle()
        {
            this.CreateVehicle();
        }

        public List Parts 
        { 
            get
            {
                return _parts;
            }
        }

        // Factory Method
        public abstract void CreateVehicle();
    }
}


As for the caller (e.g. a client application), it only needs to resolve an object using that object’s interface via the Service Locator in order to obtain access to its publicly exposed methods and properties. (see below):


FactoryPatternExample.ServiceLocator serviceLocator = new FactoryPatternExample.ServiceLocator();
IDrifter_LuxuryVehicle luxuryVehicle = serviceLocator.Resolve<IDrifter_LuxuryVehicle>();

if (luxuryVehicle != null)
{
     foreach (Part part in ((IVehicle)(luxuryVehicle)).Parts)
     {
          Console.WriteLine(string.Concat("   - ", part.Label, ": ", part.Description));
     }
}

Here are the results after making a few minor tweaks to the UI code:

The Results

What’s even more impressive is that the Service Locator now offers compile-time type checking and the ability to test each layer of the code in isolation thanks to the inclusion of the Factory Pattern:

BuildTimeError

In summary, many of the faux pas experienced when implementing the Service Locator Design Pattern can be overcome by coupling it with a slick little Factory Design Pattern. What’s more, if we apply this same logic both equitably and ubiquitously across all design patterns, then it seems unfair to take a single design pattern and criticize its integrity and usefulness in complete sequestration, because it’s often the combination of multiple design patterns that make frameworks and applications more integral and robust. Thanks for reading and keep on coding! 🙂

Advertisements

TheServiceLocatorPattern

Author: Cole Francis, Architect

BACKGROUND:

In object-oriented programming (OOP), the Dependency Inversion Principle, or DIP, stipulates that the conventional dependency relationships established from the high-level policy-setting modules, to the low-level dependency modules, are inverted (i.e. reversed), creating an obvious layer of indirection used to resolve component dependencies. Therefore, the high-level components should exist independently from a low-level component’s implementation and all its minutia.

DIP was suggested by Robert C. Martin in a paper he wrote in 1996 titled, Object Oriented Design Quality Metrics: an analysis of dependencies. Following that, there was an article that appeared in the C++ Report in May 1996 entitled “The Dependency Inversion Principle” and the books Agile Software Development, Principles, Patterns, and Practices, and Agile Principles, Patterns, and Practices in C#.

The principle inverts the way most people may think about Object Oriented Design (OOD), and the Service Locator pattern is an excellent pattern to help demonstrate DIP principles, mainly because it facilitates a runtime provisioning of chosen low-level component implementations from its higher-level componentry.

The key tenants of the Service Locator Pattern are (in layman’s terms):

  • An interface is created, which identifies a set of callable methods that the concrete service class implements.
  • A concrete service class is created, which implements the interface. The concrete class is the component where all the real work gets done (e.g. calling a database, calling a WCF method, making an Http POST Ajax call, etc…).
  • A Service Locator class is created to loosely enlist the interface and its corresponding concrete service class. Once a client application requests to resolve an enlisted type, then it’s the Service Locator’s job to resolve the appropriate interface and return it to the calling application so that the service class’s method(s) can be called.
  • A visual representation of the Dependency Inversion Pattern

To help explain the pattern a little more clearly, I’ve put together a working example of the Service Locator Pattern implementing mock services. One call simulates the retrieval of credit card authorization codes for fulfilled orders coming from a database. Once I retrieve the authorization codes, I then simulate settling them using a remote credit card service provider. Afterwards, I mimic updating our database records with the credit card settlement codes that I received back from the credit card service provider. I’ve intentionally kept the following example simple so that it’s easy to follow and explain, and I’ve also broken the code down into color-coded sections to further dissect the responsibility of each region of code:


namespace ServiceLocatorExample
{
    /// 
    /// A textbook implementation of the Service Locator Pattern.  
    /// 
    /// 
    public class ServiceLocator : IServiceLocator
    {
        #region Member Variables

        /// 
        /// An early loaded dictionary object acting as a memory map for each interface's concrete type
        /// 
        /// 
        private IDictionary services;

        #endregion

        #region IServiceLocator Methods

        /// 
        /// Resolves the concrete service type using a passed in interface
        /// 
        /// 
        public T Resolve()
        {
            try
            {
                return (T)services[typeof(T)];
            }
            catch (KeyNotFoundException)
            {
                throw new ApplicationException("The requested service is not registered");
            }
        }

        /// 
        /// Extends the service locator capabilities by allowing an interface and concrete type to 
        /// be passed in for registration (e.g. if you wrap the assembly and wish to extend the 
        /// service locator to new types added to the extended project)
        /// 
        /// 
        /// IDictionary(object, object), where the first parameterized object is the service interface 
        /// and the second parameterized object is the concrete service type
        /// 
        /// 
        public void Register(object resolver)
        {
            try
            {
                this.services[typeof(T)] = resolver;
            }
            catch (Exception)
            {
                
                throw;
            }
        }

        #endregion

        #region Constructor(s)

        /// 
        /// The service locator constructor, which resolves a supplied interface with its corresponding concrete type
        /// 
        /// 
        public ServiceLocator()
        {
            services = new Dictionary();

            // Registers the service in the locator
            this.services.Add(typeof(IGetFulfilledOrderCCAuthCodes), new GetFulfilledOrderCCAuthCodes());
            this.services.Add(typeof(IGetFulfilledOderCCSettlementCodes), new GetFulfilledOderCCSettlementCodes());
            this.services.Add(typeof(IUpdateFulfilledOrderCCSettlementCodes), new UpdateFulfilledOderCCSettlementCodes());
        }

        #endregion
    }
}


PRE-LOADING DECOUPLED RELATIONSHIPS TO A DICTIONARY OBJECT AT RUNTIME:

If you look at the all the sections I’ve highlighted in yellow, all I’m doing is declaring a Dictionary Object to act as a “registry placeholder” in the Member Variables Region, and then I’m preloading the interface and service class as a key/value pair to the service registry in the Constructor(s) Region of the code.

The key/value pairs that get stored in the Dictionary Object loosely describes the concrete class and its corresponding interface that gets registered as service objects (e.g. “IMyClass”, “MyClass”). An interface describes the methods and properties that are implemented in the concrete class, and the concrete class is type where all the real work gets accomplished. In its most primitive form, the primary job of ServiceLocator class is to store key/value pairs in a simple Dictionary object and either register or resolve those key/value pairs whenever it’s called upon to do so.

GETTING AND SETTING VALUES IN THE DICTIONARY OBJECT AT RUNTIME:

The section that’s color-coded in green denotes simple getter and setter-like methods that are publicly exposed to a consuming application, allowing that consuming application to either register new service objects in the Dictionary Object registry or resolve an existing service object in the Dictionary Object’s registry for use in a client application.

In fact, listed below is a textbook example of how a client application would resolve an existing service object in the Dictionary Object’s registry for use. In this example I’m resolving the IGetFulfilledOrderCCAuthCodes interface to its concrete type and then calling its GetFulfilledOrderCCAuthCodes() method using a console application that I quickly threw together…


/// 
/// Gets the fulfilled orders credit card authorization codes to settle on
/// 
/// 
private static List GetFulfilledOrderCCAuthCodes()
{
    ServiceLocatorExample.ServiceLocator locator2 = new ServiceLocatorExample.ServiceLocator();
    IGetFulfilledOrderCCAuthCodes o = locator2.Resolve();
    return o.GetFulfilledOrderCCAuthCodes();
}


CONGRATULATIONS! YOU’RE DONE:

Assuming that someone has already written logic to retrieve the fulfilled order authorization codes from the database, then your part is done! I really wish there was more to it than this so that I would look like some sort of architectural superhero, but alas there isn’t. Thus, if all you were looking to get out of this post is how to implement a textbook example of the Service Locator design pattern, then you don’t need to go any further. However, for those of you who want to know the advantages and disadvantages of the Service Locator design pattern then please keep reading:

THE ADVANTAGES:

  • The Service Locator Pattern follows many well-recognized architectural principles, like POLA, Hollywood, KISS, Dependency Inversion, YAGNI, and others…
  • Although the Service Locator Pattern is not considered to be a lightweight pattern, it’s still very simple to learn and is easily explainable to others, which means that your junior developer’s eyes won’t pop out of their heads when you attempt to explain the concept to them.
    • This truly is a framework pattern that you can teach a less knowledgeable person over a lunch hour and expect them to fully understand when you’re done, because the Service Locator framework wires everything up using an minimal number of resources (e.g. a Dictionary object containing key/value pairs and the ability to read from and (optionally) write to the Dictionary object).
  • The Service Locator design pattern allows you to quickly and efficiently create a loosely coupled runtime linker that’s ideal for separating concerns across the entire solution, as each type is concerned only about itself and doesn’t care what any of the other components do.
  • For you architectural purists out there, just be aware that using the Service Locator design pattern doesn’t preclude you from coupling it with good Dependency Injection and Factory Pattern frameworks. In fact, by doing so you have the potential of creating a lasting framework that meets the conditions of both SOLID and POLA design principles, as well as many others. Perhaps I’ll make this the topic of my next architectural discussion…

THE DISADVANTAGES:

  • The services (i.e. Key/value pairs that represent concrete classes) that get registered in the Service Locator object are often considered “black box” items to consumers of the Service Locator class, meaning service objects and their dependencies are completely abstracted from the applications that call it. This loosely coupled structure makes it extremely difficult to track down issues without development access to the source code for not only the Service Locator itself, but also all of the dependent service objects that get registered by it at runtime.
    • If you find yourself in this situation and you don’t have access to the Service Locator source code, then tools like the Microsoft ILDasm or the RedGate’s .NET Reflector are occasionally able to shed some light on what’s going on inside the Service Locator assembly; however, if the code happens to be obfuscated or if hidden dependencies are completely unresolvable, then deciphering issues can become an exercise in futility. For this very reason, the Service Locator Pattern violates ACID Principles, which is why some architectural gurus consider the Service Locator design to be more of a design anti-pattern.
  • Because Service Locator’s dictionary is constructed using a key/value concept, all key names must be unique, meaning that it’s not very well-suited for distributed systems without adding more validation checks around the Register method’s dictionary insertion code.
  • Testing the registered objects becomes a difficult process because we aren’t able to test each object in isolation, as registered service objects are considered “black box” items to both the Service Locator and its callers.
  • As I previously mentioned, objects are “late-bound”, which means that a caller is going to burn up some CPU cycles waiting the Service Locator to find the service’s registry entry in the Dictionary object and return it to them, and then they still have to invoke that object “late-bound”. Sure the time is minimal, but it’s still time that isn’t being spent on enhancing something more valuable…like the user experience.
  • There are also some concerns from a security standpoint. Keep in mind that my ServiceLocator class allows people to dynamically register their own objects at runtime (see the code snippet below). Who knows what types of malicious service objects might get registered? What if our ServiceLocator class only performed a minimal set of validations before executing a method on a service object? Now that’s an awfully scary thought.



/// 
/// Extends the service locator capabilities by allowing an interface and concrete type to 
/// be passed in for registration (e.g. if you wrap the assembly and wish to extend the 
/// service locator to new types added to the extended project)
/// 
///
public void Register(object resolver)
{
    try
    {
       this.services[typeof(T)] = resolver;
    }
    catch (Exception)
    {
       throw;
    }
}



SOME FINAL TALKING POINTS:

As you can see, the Service Locator Design Pattern is very simple to explain and understand, but it certainly isn’t a “one size fits all” design pattern, and a fair degree of caution should be exercised before choosing it as a framework to build your solution on. You might even consider coupling it or substituting it with a more robust pattern, like one that offers the same capabilities but resolves its dependency objects at build-time instead of runtime (e.g. Dependency Injection).

Personally, I think this pattern’s “sweet spot” is for applications that: (1) Have a very narrow design scope; (2) Are built for in-house use and not third-party distribution; (3) Leverage service objects that are well-known and well-tested by a development team; (4) Aren’t designed for blazing speed. Thanks for reading and keep on coding! 🙂