0

Я хотел был бы иметь возможность зарегистрировать 2 класс для того же интерфейса в моем контейнере Unity. Затем я хотел бы выбрать текущую реализацию на основе параметра.Web Api and Unity IoC

Вот мой интерфейс:

public interface ICheckService 
{ 
    HttpResponseMessage Validate(string p1, string p2); 
} 
} 

Мои услуги:

public class CheckService1 : ICheckService 
{ 
    public HttpResponseMessage Validate(string p1, string p2) 
    { 
     /////code 
    } 
} 

public class CheckService2 : ICheckService 
{ 
    public HttpResponseMessage Validate(string p1, string p2) 
    { 
     ////code 
    } 
} 

В bootstraper.cs я объявляю свои услуги:

 `container.RegisterType<ICheckService, CheckService1>();` 
     `container.RegisterType<ICheckService, CheckService2>();` 

Мой контроллер API:

public class ServiceController : ApiController 
{ 
    private readonly ICheckService _checkService; 

    public ServiceController(ICheckService checkService) 
    { 
     _checkService = checkService; 
    } 
    [HttpGet] 
    public HttpResponseMessage Validate(string p1, string p2) 
    { 
     return _checkService.Validate(p1, p2); 
    } 
} 

Теперь я хотел бы, когда я закрою свой api, выбрать реализацию на основе параметра p1.

Если p1 равно Сервису 1, то метод Validate вызывается из класса Service1, а если p1 равно Service2, метод validate вызывается из класса Service2.

Благодарим за помощь.

ответ

1

Для этого вы должны использовать завод, а не контейнер. Реализация на заводе может запросить правильную реализацию из контейнера внутри страны (т. Е. Это всего лишь деталь реализации, а не что-то, о чем должен знать заводской запросчик).

Но дело в том, что использование IoC напрямую не подходит для вашего случая.

public class ServiceController : ApiController 
{ 
    private readonly ICheckServiceFactory _checkFactory; 

    public ServiceController(ICheckServiceFactory factory) 
    { 
     _checkFactory = factory; 
    } 
    [HttpGet] 
    public HttpResponseMessage Validate(string p1, string p2) 
    { 
     var service = _checkFactory.Create(p1); 
     service.Validate(p1, p2); 
    } 
} 
0

CheckService1 и CheckService2 в вашем случае являются классами реализации/подробностями проверки. Вы можете создать CheckServiceFactory, который может создавать эти классы для вас во время выполнения. Зарегистрируйте класс фабрики, а не классы реализации.

0

Другой вариант - использование шаблона стратегии. Класс будет действовать как завод проверки. Factory class будет инициализировать словарь ICheckServices. Завод (ICheckServiceFactory) будет зарегистрирован, используя IoC контейнер выбора:

public interface ICheckServiceFactory 
{ 
    string Validate(string validationStrategy, string stringToValidate); 
} 

public class CheckServiceFactory : ICheckServiceFactory 
{ 
    private readonly Dictionary<string, ICheckService> _checkServices; 

    public CheckServiceFactory() 
    { 
     _checkServices = new Dictionary<string, ICheckService> 
     { 
      {"cash", new CheckService1()}, 
      {"card", new CheckService2()} 
     }; 
    } 

    public string Validate(string validationStrategy, string stringToValidate) 
    { 
     return $"Parameter '{stringToValidate}' is Valid equal {_checkServices[validationStrategy].Validate(stringToValidate)} using {_checkServices[validationStrategy].CheckType}"; 
    } 
} 

каждая проверка услуг реализует ICheckServices:

public interface ICheckService 
{ 
    string CheckType { get; } 

    bool Validate(string validateMe); 
} 

public class CheckService2 : ICheckService 
{ 
    public string CheckType { get; } 

    public CheckService2() 
    { 
     CheckType = "CheckService2"; 
    } 

    public bool Validate(string validateMe) 
    { 
     return true; 
    } 
} 

public class CheckService1 : ICheckService 
{ 
    public string CheckType { get; } 

    public CheckService1() 
    { 
     CheckType = "CheckService1"; 
    } 

    public bool Validate(string validateMe) 
    { 
     return true; 
    } 
} 

Так что ваш контроллер службы будет выглядеть подобно тому, как вы изначально хотите его выглядят так:

public class ServiceController : ApiController 
{ 
    private readonly ICheckServiceFactory _checkServiceFactory; 

    public ServiceController(ICheckServiceFactory factory) 
    { 
     _checkServiceFactory = factory; 
    } 
    [HttpGet] 
    public HttpResponseMessage Validate(string p1, string p2) 
    { 
     return _checkServiceFactory.Validate(p1, p2); 
    } 
} 
Смежные вопросы