2013-03-28 88 views
0

我希望能夠在Unity容器中爲同一個接口註冊2個類。 然後,我想選擇基於參數的當前實現。Web Api和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); 
    } 
} 

現在,我想,當我cal我的api時,選擇基於p1參數的實現。

如果p1等於Service1,則從Service1類調用Validate方法,如果p1等於Service2,則從Service2類調用validate方法。

感謝您的幫助。

回答

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

另一種選擇是通過使用策略模式。一個班級將充當檢查服務的工廠。工廠類將初始化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); 
    } 
}