[Architecture Pattern] service locator

Source: Internet
Author: User

Motivation

Service locator is a common mode during system development. The pattern can be found in the inversion of control containers and the dependency injection pattern written by Martin Fowler. Service locator defines the responsibility of generating, storing, and obtaining objects in the BLL layer, so that the system does not need to know how to generate and store objects when obtaining objects, effectively reduces system coupling.

 

At the same time, learning service locator brings the concept of space into the architecture design. When designing the architecture, you can use service locator as the encapsulation of the architecture space. Create an object generated by the object and store it in the service locator so that the target architecture "exists" and a group of objects can be used.

 

This article introduces the implementation of a service locator, which defines the responsibilities and interactions between objects to complete the functions and responsibilities that the service locator should provide. Make a record for yourself and hope to help developers who need it.

 

Structure

The usercountservice created by [Architecture Pattern] repository is used as an example. In addition, The bll layer uses service locator to encapsulate the generation, storage, and retrieval of usercountservice objects. The sample structure is as follows:

 

 

Major participants include:

 

Servicelocator
-Provides the object storage function for the system.
-Provides storage objects for the system.

 

Client
-Use the usercountservice in servicelocator memory.

 

Usercountservice
-Use user data in the system to calculate various counts.
-Generated by the client or servicelocator.

 

The following figure shows the interaction process between objects.

 


 

Practice

Service locator is composed of two types of operation logic: positioning logic and generation logic. The positioning logic is the core of the entire service locator. It defines the responsibilities of Object Storage and object acquisition. Objects must be generated before they can be used. The generation logic defines the responsibility of object generation. Then, a set of service locator is implemented to parse the operation logic in the service locator and help developers understand the service locator mode.

 

Model column download

For more information, see servicelocatorsample.

 

Positioning Logic

First, create the servicelocatorsample. BLL project, and create a servicelocator object to encapsulate the positioning logic of service locator: servicelocator provides the setinstance method, allowing the system to store various types of objects. In addition, servicelocator provides the getinstance method, allowing the system to retrieve previously stored objects.

 

public partial class ServiceLocator{    // Fields      private readonly Dictionary<Type, object> _serviceDictionary = new Dictionary<Type, object>();    // Methods    public TService GetInstance<TService>() where TService : class    {        // Result        TService service = default(TService);        // Exist        if (_serviceDictionary.ContainsKey(typeof(TService)) == true)        {            service = _serviceDictionary[typeof(TService)] as TService;        }        // Return        return service;    }    public void SetInstance<TService>(TService service) where TService : class    {        #region Require        if (service == null) throw new ArgumentNullException();        #endregion        // Set        if (_serviceDictionary.ContainsKey(typeof(TService)) == false)        {            _serviceDictionary.Add(typeof(TService), service);        }        else        {            _serviceDictionary[typeof(TService)] = service;        }    }}

 

In addition, servicelocator also applies Singleton pattern, enabling the system to conveniently use servicelocator.

 

public partial class ServiceLocator{    // Singleton    private static ServiceLocator _current;    public static ServiceLocator Current    {        get        {            if (_current == null)            {                _current = new ServiceLocator();            }            return _current;        }        set        {            _current = value;        }    }}

 

External generation logic

Create a console project and use servicelocator to obtain the number of persons that usercountservice uses to print. Usercountservice is generated and injected into servicelocator by the console project.

 

class Program{    static void Main(string[] args)    {        // Initialize        InitializeServiceLocator();                    // UserCountService        UserCountService userCountService = ServiceLocator.Current.GetInstance<UserCountService>();        // Print        Console.WriteLine("All Count : " + userCountService.GetAllCount());        Console.WriteLine("Men Count : " + userCountService.GetMenCount());        // End        Console.ReadLine();    }    static void InitializeServiceLocator()    {        // UserRepository        IUserRepositoryProvider userRepositoryProvider = new SqlUserRepositoryProvider();        UserRepository userRepository = new UserRepository(userRepositoryProvider);        UserCountService userCountService = new UserCountService(userRepository);        // SetInstance        ServiceLocator.Current.SetInstance<UserCountService>(userCountService);    }}

 

 

Internal generation logic

So far, the sample program can use servicelocator to obtain the number of persons that usercountservice uses to print. However, usercountservice is generated and stored in servicelocator by a function other than servicelocator. This makes it necessary to re-create the object generation and storage functions for each reuse.

 

To increase the reusability of servicelocator, modify the servicelocator object and encapsulate the generation logic of service locator: servicelocator provides the createinstance method, allowing the system to create various types of objects. In addition, when the system fails to retrieve the previously stored objects, it will use createinstance to generate the objects.

 

(Because it is a simulation example, it simplifies the design of many usercountservices, and uses a direct establishment method. The actual project can use various IOC frameworks to generate injection, or apply various factory pattern, which can improve the reusability of servicelocator .)

 

public partial class ServiceLocator{    // Fields      private readonly Dictionary<Type, object> _serviceDictionary = new Dictionary<Type, object>();    // Methods    protected virtual TService CreateInstance<TService>() where TService : class    {        // Result        TService service = default(TService);        // UserCountService        if (typeof(TService) == typeof(UserCountService))        {            IUserRepositoryProvider userRepositoryProvider = new CsvUserRepositoryProvider();            UserRepository userRepository = new UserRepository(userRepositoryProvider);            UserCountService userCountService = new UserCountService(userRepository);            service = userCountService as TService;        }        // Return        return service;    }    public TService GetInstance<TService>() where TService : class    {        // Result        TService service = default(TService);        // Exist        if (_serviceDictionary.ContainsKey(typeof(TService)) == true)        {            service = _serviceDictionary[typeof(TService)] as TService;        }        if (service != null) return service;        // Create        service = this.CreateInstance<TService>();        if (service != null) this.SetInstance<TService>(service);        // Return        return service;    }    public void SetInstance<TService>(TService service) where TService : class    {        #region Require        if (service == null) throw new ArgumentNullException();        #endregion        // Set        if (_serviceDictionary.ContainsKey(typeof(TService)) == false)        {            _serviceDictionary.Add(typeof(TService), service);        }        else        {            _serviceDictionary[typeof(TService)] = service;        }    }}

 

 

Finally, modify the console project and remove the logic for generating usercountservice in the project. In addition, servicelocator is used to obtain the number of persons used for printing usercountservice.

 

class Program{    static void Main(string[] args)    {        // UserCountService        UserCountService userCountService = ServiceLocator.Current.GetInstance<UserCountService>();        // Print        Console.WriteLine("All Count : " + userCountService.GetAllCount());        Console.WriteLine("Men Count : " + userCountService.GetMenCount());        // End        Console.ReadLine();    }}

 

Postscript

In practice, the entire service locator can be found by eye-catching developers that it is similar to IOC framework. The difference between service locato and IOC framework is mainly in: IOC framework is mainly responsible for object generation, and service locator is mainly responsible for Object Storage and object acquisition. After the development, almost both of them have three responsibilities: Object generation, object storage, and object acquisition. In another way, most IOC frameworks encapsulate the duties of service locator. Some service locator packages the responsibilities of IOC framework. Although the results look the same, the design of the two is different.

 

There are many actual service locator versions. These actual versions are divided and designed according to requirements. The responsibilities of object generation, object storage, and object acquisition in The bll layer are used to improve the reusability and maintainability of the overall architecture. In addition to meeting the customer's needs, the success or failure of a system is also an important part of these additional non-functional requirements. This allows developers who take over maintenance to go home for dinner early. : D

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.