मैं एएसपीनेट कोर 2.2 में टाइप किए गए क्लाइंट का उपयोग करके एपीआई को कॉल करने के लिए रीफिट का उपयोग कर रहा हूं जो वर्तमान में हमारे कॉन्फ़िगरेशन विकल्पों में से एक बेसएड्रेस का उपयोग करके बूटस्ट्रैप किया गया है:

services.AddRefitClient<IMyApi>()
        .ConfigureHttpClient(c => { c.BaseAddress = new Uri(myApiOptions.BaseAddress);})
        .ConfigurePrimaryHttpMessageHandler(() => NoSslValidationHandler)
        .AddPolicyHandler(pollyOptions);

हमारे कॉन्फ़िगरेशन जेसन में:

"MyApiOptions": {
    "BaseAddress": "https://server1.domain.com",
}

हमारे IMyApi इंटरफ़ेस में:

public IMyAPi interface {
        [Get("/api/v1/question/")]
        Task<IEnumerable<QuestionResponse>> GetQuestionsAsync([AliasAs("document_type")]string projectId);
}

उदाहरण वर्तमान सेवा:

public class MyProject {
     private IMyApi _myApi;
     public MyProject (IMyApi myApi) {
        _myApi = myApi;
     }

    public Response DoSomething(string projectId) {
        return _myApi.GetQuestionsAsync(projectId);
    }
}

अब मुझे रनटाइम पर डेटा के आधार पर अलग-अलग बेसएड्रेस का उपयोग करने की आवश्यकता है। मेरी समझ यह है कि रीफिट एचटीपी क्लाइंट का एक उदाहरण डीआई में जोड़ता है और इसलिए रनटाइम पर बेस एड्रेस को स्विच करना सीधे मल्टीथ्रेडेड ऐप में काम नहीं करेगा। अभी IMyApi का एक उदाहरण इंजेक्ट करना और इंटरफ़ेस विधि GetQuestionsAsync को कॉल करना वास्तव में सरल है। उस समय बेसएड्रेस सेट करने में बहुत देर हो चुकी होती है। यदि मेरे पास एकाधिक बेस एड्रेस हैं, तो क्या गतिशील रूप से किसी एक को चुनने का कोई आसान तरीका है?

उदाहरण विन्यास:

    "MyApiOptions": {
        "BaseAddresses": {
            "BaseAddress1": "https://server1.domain.com",
            "BaseAddress2": "https://server2.domain.com"
        }
}

उदाहरण भविष्य सेवा:

public class MyProject {
     private IMyApi _myApi;
     public MyProject (IMyApi myApi) {
        _myApi = myApi;
     }

    public Response DoSomething(string projectId) {
        string baseUrl = SomeOtherService.GetBaseUrlByProjectId(projectId);

        return _myApi.UseBaseUrl(baseUrl).GetQuestionsAsync(projectId);
    }
}

अपडेट करें स्वीकृत उत्तर के आधार पर मैं निम्नलिखित के साथ समाप्त हुआ:

public class RefitHttpClientFactory<T> : IRefitHttpClientFactory<T>
{
    private readonly IHttpClientFactory _clientFactory;

    public RefitHttpClientFactory(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }

    public T CreateClient(string baseAddressKey)
    {
        var client = _clientFactory.CreateClient(baseAddressKey);

        return RestService.For<T>(client);
    }
}
8
sarin 29 अक्टूबर 2019, 19:52

1 उत्तर

सबसे बढ़िया उत्तर

क्लाइंट के बजाय ClientFactory इंजेक्ट करें:

public class ClientFactory
{
    public IMyApi CreateClient(string url) => RestService.For<IMyApi>(url);
}

public class MyProject {
     private ClientFactory _factory;
     public MyProject (ClientFactory factory) {
        _factory = factory;
     }

    public Response DoSomething(string projectId) {
        string baseUrl = SomeOtherService.GetBaseUrlByProjectId(projectId);
        var client = _factory.CreateClient(baseUrl);

        return client.GetQuestionsAsync(projectId);
    }
}
3
Rik 29 अक्टूबर 2019, 20:00