「C Sharpとネットワーク - HttpClient」の版間の差分

ナビゲーションに移動 検索に移動
 
337行目: 337行目:
     }
     }
   }
   }
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="c#">
using System;
using System.Threading.Tasks;
using System.Net.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
class Program
{
    static async Task Main(string[] args)
    {
      var host = Host.CreateDefaultBuilder(args).ConfigureServices((context, services) => {
          // 方法 1 : 異なる名前で複数のHttpClientを登録
          services.AddHttpClient("github", client => {
            client.BaseAddress = new Uri("https://api.github.com/");
            client.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
          });
          services.AddHttpClient("weather", client => {
            client.BaseAddress = new Uri("https://api.weather.com/");
            client.DefaultRequestHeaders.Add("User-Agent", "Weather-Service");
          });
          // 方法 2 : 型付きHttpClientを各APIサービス用に登録
          services.AddHttpClient<GitHubService>();
          services.AddHttpClient<WeatherService>();
          // 方法 3 : 設定情報を含むサービスを登録
          services.Configure<ApiSettings>(context.Configuration.GetSection("ApiSettings"));
          services.AddHttpClient<MultiBaseUriService>();
          services.AddTransient<IMultiApiService, MultiApiService>();
      }).Build();
      var service = host.Services.GetRequiredService<IMultiApiService>();
      await service.RunExample();
    }
}
// APIの設定を保持するクラス
public class ApiSettings
{
    public Dictionary<string, string> BaseUrls { get; set; } = new();
}
// 複数のベースURIを扱うサービス
public class MultiBaseUriService
{
    private readonly HttpClient _httpClient;
    private readonly ApiSettings _settings;
    private readonly Dictionary<string, string> _baseUrls;
    public MultiBaseUriService(HttpClient client, IOptions<ApiSettings> settings)
    {
      _httpClient = client;
      _settings = settings.Value;
      _baseUrls = _settings.BaseUrls;
    }
    public async Task<string> SendRequest(string apiKey, string endpoint)
    {
      if (!_baseUrls.TryGetValue(apiKey, out var baseUrl))
      {
          throw new ArgumentException($"Unknown API key: {apiKey}");
      }
      var fullUrl = new Uri(new Uri(baseUrl), endpoint);
      return await _httpClient.GetStringAsync(fullUrl);
    }
}
// GithubのAPI用サービス
public class GitHubService
{
    private readonly HttpClient _httpClient;
    public GitHubService(HttpClient client)
    {
      _httpClient = client;
      _httpClient.BaseAddress = new Uri("https://api.github.com/");
      _httpClient.DefaultRequestHeaders.Add("User-Agent", "GitHub-Service");
    }
    public async Task<string> GetRepositoryInfo(string repo)
    {
      return await _httpClient.GetStringAsync($"repos/{repo}");
    }
}
// 気象API用サービス
public class WeatherService
{
    private readonly HttpClient _httpClient;
    public WeatherService(HttpClient client)
    {
      _httpClient = client;
      _httpClient.BaseAddress = new Uri("https://api.weather.com/");
      _httpClient.DefaultRequestHeaders.Add("User-Agent", "Weather-Service");
    }
    public async Task<string> GetWeatherInfo(string location)
    {
      return await _httpClient.GetStringAsync($"weather/{location}");
    }
}
// 複数APIを利用するサービスのインターフェース
public interface IMultiApiService
{
    Task RunExample();
}
// 複数のAPIを利用する実装
public class MultiApiService : IMultiApiService
{
    private readonly IHttpClientFactory  _clientFactory;
    private readonly GitHubService      _githubService;
    private readonly WeatherService      _weatherService;
    private readonly MultiBaseUriService _multiBaseUriService;
    public MultiApiService(IHttpClientFactory clientFactory, GitHubService githubService, WeatherService weatherService,
                          MultiBaseUriService multiBaseUriService)
    {
      _clientFactory = clientFactory;
      _githubService = githubService;
      _weatherService = weatherService;
      _multiBaseUriService = multiBaseUriService;
    }
    public async Task RunExample()
    {
      // 方法 1 : 名前付きHttpClientの使用
      try
      {
          var githubClient = _clientFactory.CreateClient("github");
          var weatherClient = _clientFactory.CreateClient("weather");
          var githubResponse = await githubClient.GetStringAsync("repos/dotnet/runtime");
          var weatherResponse = await weatherClient.GetStringAsync("weather/tokyo");
          Console.WriteLine("Named Clients Response:");
          Console.WriteLine($"GitHub: {githubResponse.Substring(0, 100)}...");
          Console.WriteLine($"Weather: {weatherResponse.Substring(0, 100)}...");
      }
      catch (Exception ex)
      {
          Console.WriteLine($"Named clients error: {ex.Message}");
      }
      // 方法 2 : 型付きHttpClientの使用
      try
      {
          var githubInfo = await _githubService.GetRepositoryInfo("dotnet/runtime");
          var weatherInfo = await _weatherService.GetWeatherInfo("tokyo");
          Console.WriteLine("\nTyped Clients Response:");
          Console.WriteLine($"GitHub: {githubInfo.Substring(0, 100)}...");
          Console.WriteLine($"Weather: {weatherInfo.Substring(0, 100)}...");
      }
      catch (Exception ex)
      {
          Console.WriteLine($"Typed clients error: {ex.Message}");
      }
      // 方法 3 : 動的なベースURI切り替え
      try
      {
          var githubResponse = await _multiBaseUriService.SendRequest("github", "repos/dotnet/runtime");
          var weatherResponse = await _multiBaseUriService.SendRequest("weather", "weather/tokyo");
          Console.WriteLine("\nMulti Base URI Service Response:");
          Console.WriteLine($"GitHub: {githubResponse.Substring(0, 100)}...");
          Console.WriteLine($"Weather: {weatherResponse.Substring(0, 100)}...");
      }
      catch (Exception ex)
      {
          Console.WriteLine($"Multi base URI error: {ex.Message}");
      }
    }
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>

案内メニュー