我有两个实现接口的类。这两个类都执行位置搜索功能。同样在两个classe构造函数中,有一个取决于类
的通用功能Google:IGoogle
public NearBySearch(IWebPortalApiClient webPortalApiClient)
{
var serverString = ConfigHelper.GetAppSetting(ConfigConstants.APIServerType);
var server = (WebPortalServer)Enum.Parse(typeof(WebPortalServer), serverString, true);
this._webPortalApiClient = webPortalApiClient;
this.GoogleKey = $"&key={ConfigHelper.GetAppSetting(ConfigConstants.Googlekey)}";
this._webPortalApiClient.Init(server);
}
Yelp:IYelp
public BusinessSearch(IWebPortalApiClient webPortalApiClient)
{
var serverString = ConfigHelper.GetAppSetting(ConfigConstants.APIServerType);
var server = (WebPortalServer)Enum.Parse(typeof(WebPortalServer), serverString, true);
this._webPortalApiClient = webPortalApiClient;
this._webPortalApiClient.AccessToken = ConfigHelper.GetAppSetting(ConfigConstants.YelpApiKey);
this._webPortalApiClient.Init(server, this._webPortalApiClient.AccessToken);
}
对于Google,我们必须将密钥作为查询参数发送,而在Yelp中,我们必须将密钥作为授权标头发送
在API控制器中,我同时注入了两者
IGoogle
private IYelpController _yelpController;
private IGoogleController _googleController;
public PlaceSearchController(IYelpController yelpController, IGoogleController googleController)
{
this._yelpController = yelpController;
this._googleController = googleController;
}
我们在API中调用的函数就像
[HttpGet]
public async Task<IHttpActionResult> GetAllBusiness(int web, decimal latitude, decimal longitude, string radius = null)
{
try
{
if (web == (int)PlaceSearch.Yelp)
{
var result = await _yelpController.GetAllBusiness(latitude, longitude, radius);
var response = new Response<Common.Models.Yelp.Yelp>(ResponseConstants.Success, ResponseConstants.SuccessMessage, result);
return Ok(response);
}
else if(web == (int)PlaceSearch.Google)
{
if(radius == null)
{
throw new Exception();
}
var result = await _googleController.GetAllNearByPlaces(latitude, longitude, radius);
var response = new Response<Common.Models.Google.Google>(ResponseConstants.Success, ResponseConstants.SuccessMessage, result);
return Ok(response);
}
throw new Exception();
}
catch (Exception ex)
{
var response = new Response<Object>(ResponseConstants.Forbidden, ResponseConstants.FailureMessage, null);
return Ok(response);
}
}
在构造函数中都调用了函数下面我面临的问题
public IWebPortalApiClient Init(WebPortalServer server, string accessToken = null)
{
WebPortalServer = server;
AccessToken = accessToken;
return this;
}
执行Yelp时,会按预期方式传递asses令牌,但与此同时,我们不会在Google中传递访问令牌,这会将访问令牌设置为null。
由于这个问题,我无法调用Yelp API,因为它找不到访问令牌。
有没有一种方法可以在条件基础上注入依赖性。我们为此使用Unity容器。
Web Portal客户端
public class WebPortalApiClient : IWebPortalApiClient
{
public WebPortalServer WebPortalServer { get; set; }
public string AccessToken { get; set; }
private string ServerUrl
{
get
{
switch (WebPortalServer)
{
case WebPortalServer.Dev:
return null;
case WebPortalServer.QA:
return null;
case WebPortalServer.Demo:
return null;
case WebPortalServer.Production:
return null;
case WebPortalServer.Localhost:
return "http://localhost:63695/";
case WebPortalServer.Integration:
return null;
case WebPortalServer.UAT:
return null;
default:
throw new ArgumentOutOfRangeException();
}
}
}
public async Task<HttpContent> InvokeApi(string path, HttpAction action, HttpContent content = null, TimeSpan? overrideTimeout = null, string externalServer = null)
{
var sUrl = externalServer == null ? ServerUrl : externalServer;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(sUrl);
if (overrideTimeout.HasValue)
{
client.Timeout = overrideTimeout.Value;
}
//this.Log("Connecting to {0} Api at {1}".Fmt(WebPortalServer, ServerUrl));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", AccessToken);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response;
switch (action)
{
case HttpAction.Get:
response = await client.GetAsync(path);
break;
case HttpAction.Post:
response = await client.PostAsync(path, content);
break;
case HttpAction.Put:
response = await client.PutAsync(path, content);
break;
case HttpAction.Delete:
response = await client.DeleteAsync(path);
break;
default:
throw new ArgumentOutOfRangeException("action", action, null);
}
return response.IsSuccessStatusCode ? response.Content : null;
}
}
public IWebPortalApiClient Init(WebPortalServer server, string accessToken = null)
{
WebPortalServer = server;
AccessToken = accessToken;
return this;
}
}