CODESAMPLE

Service Locator - C#

Share on:

The Service Locator pattern manages dependencies by providing a central point of access to services. Instead of a class directly creating or finding its dependencies, it asks the locator for them. This promotes loose coupling and makes it easier to switch implementations. The C# example utilizes a static class ServiceLocator to hold service registrations in a Dictionary. Resolve<T>() retrieves a service, creating a new instance if not already registered (using a default constructor). While dependency injection is generally preferred in modern C#, Service Locator can be useful in legacy systems or scenarios where complete control over dependency resolution isn’t possible upfront.

using System;
using System.Collections.Generic;

public interface IOperation
{
    string Execute();
}

public class OperationA : IOperation
{
    public string Execute() => "Operation A Executed";
}

public class OperationB : IOperation
{
    public string Execute() => "Operation B Executed";
}

public static class ServiceLocator
{
    private static readonly Dictionary<Type, object> services = new();

    public static void Register<T>(T service) => services[typeof(T)] = service;

    public static T Resolve<T>() => (T)(services.ContainsKey(typeof(T)) ? services[typeof(T)] : Activator.CreateInstance(typeof(T)));
}

public class Client
{
    public void RunOperation(string operationType)
    {
        IOperation operation;
        switch (operationType)
        {
            case "A":
                operation = ServiceLocator.Resolve<IOperation>();
                break;
            case "B":
                operation = ServiceLocator.Resolve<IOperation>();
                break;
            default:
                throw new ArgumentException("Invalid operation type");
        }

        Console.WriteLine(operation.Execute());
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        ServiceLocator.Register(new OperationA());
        ServiceLocator.Register<IOperation>(new OperationB()); //Register explicitly with interface

        var client = new Client();
        client.RunOperation("A");
        client.RunOperation("B");
    }
}