关于如何实现条件依赖的建议?

时间:2019-03-09 06:13:21

标签: c# asp.net-mvc asp.net-mvc-5 asp.net-web-api2 unity-container

我有两个实现接口的类。这两个类都执行位置搜索功能。同样在两个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;
    }
}

0 个答案:

没有答案