Created
January 23, 2023 18:13
-
-
Save Stroniax/c6ffd55b9506d4bfb7feb4036bc895b5 to your computer and use it in GitHub Desktop.
Example StrongInject Application Configured HttpClient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// See https://aka.ms/new-console-template for more information | |
using StrongInject; | |
using System.Net; | |
using System.Net.Http.Json; | |
namespace StrongInjectConfiguredHttpClientExample; | |
public class Program | |
{ | |
public async Task Main(string[] args) | |
{ | |
await using var container = new AppContainer(args); | |
await container.RunAsync(async program => | |
{ | |
await program.UpdateRecords(); | |
}); | |
} | |
} | |
// end | |
public interface IFileReader | |
{ | |
IAsyncEnumerable<string?> ReadAllLines(string fileName); | |
} | |
public class FileReader : IFileReader | |
{ | |
public async IAsyncEnumerable<string?> ReadAllLines(string fileName) | |
{ | |
await using var file = File.OpenRead(fileName); | |
using var reader = new StreamReader(file); | |
while (!reader.EndOfStream) | |
{ | |
yield return await reader.ReadLineAsync(); | |
} | |
} | |
} | |
/// <summary> | |
/// Sends file information to an HTTP endpoint to update some entity. | |
/// </summary> | |
public class FileContentHttpClient | |
{ | |
private readonly HttpClient _http; | |
public FileContentHttpClient(HttpClient http) => _http = http; | |
public async Task UpdateRecord(FileContentUpdate update) => await _http.PutAsJsonAsync($"/records/{update.RecordId}", update); | |
} | |
/// <summary> | |
/// Updates global state at some HTTP endpoint, such as tracking when a program ran last. | |
/// </summary> | |
public class GlobalStateHttpClient | |
{ | |
private readonly HttpClient _http; | |
public GlobalStateHttpClient(HttpClient http) => _http = http; | |
public async Task UpdateGlobalState(GlobalStateUpdate update) => await _http.PostAsJsonAsync("/applications/check-in", update); | |
} | |
public record GlobalStateUpdate( | |
int UpdatedFileCount, | |
DateTimeOffset StartTime, | |
DateTimeOffset CompleteTime, | |
string Application, | |
bool HadErrors | |
); | |
public record FileContentUpdate( | |
int RecordId, | |
DateTimeOffset Posted | |
// other members... | |
) | |
{ | |
public static FileContentUpdate Parse(string line) => throw new NotImplementedException(); | |
} | |
public record ContentUpdateService( | |
IFileReader FileReader, | |
FileContentHttpClient FileContent, | |
GlobalStateHttpClient GlobalState, | |
string[] FileNames | |
) | |
{ | |
public async Task UpdateRecords() | |
{ | |
var updatedFileCount = 0; | |
var start = DateTimeOffset.UtcNow; | |
try | |
{ | |
foreach (var fileName in FileNames) | |
{ | |
updatedFileCount++; | |
await ProcessFile(fileName); | |
} | |
} | |
catch | |
{ | |
await UpdateGlobalState(updatedFileCount, start, true); | |
return; | |
} | |
await UpdateGlobalState(updatedFileCount, start, false); | |
} | |
private Task UpdateGlobalState(int updatedFileCount, DateTimeOffset start, bool hadErrors) | |
=> GlobalState.UpdateGlobalState( | |
new( | |
updatedFileCount, | |
start, | |
DateTimeOffset.UtcNow, | |
"My-Application", | |
hadErrors)); | |
public async Task ProcessFile(string fileName) | |
{ | |
await foreach (var line in FileReader.ReadAllLines(fileName)) | |
{ | |
var record = FileContentUpdate.Parse(line!); | |
await FileContent.UpdateRecord(record); | |
} | |
} | |
} | |
[Register<FileReader, IFileReader>] | |
[Register<ContentUpdateService>] | |
public partial class AppContainer : IAsyncContainer<ContentUpdateService> | |
{ | |
[Instance] | |
private readonly string[] _args; | |
public AppContainer(string[] args) => _args = args; | |
[Factory] | |
public static GlobalStateHttpClient CreateGlobalStateClient() | |
{ | |
return new GlobalStateHttpClient( | |
new HttpClient( | |
new HttpClientHandler() | |
{ | |
PreAuthenticate = true, | |
Credentials = new CredentialCache() | |
{ | |
{ new Uri("http://app-api.com/"), "Negotiate", CredentialCache.DefaultNetworkCredentials } | |
} | |
}) | |
{ | |
BaseAddress = new Uri("http://app-api.com/"), | |
}); | |
} | |
[Factory] | |
public static FileContentHttpClient CreateFileContentClient() | |
{ | |
return new FileContentHttpClient( | |
new HttpClient( | |
new HttpClientHandler() | |
{ | |
Credentials = new NetworkCredential("My-service-accoutn", "securepswd"), | |
PreAuthenticate = true, | |
} | |
) | |
{ | |
BaseAddress = new Uri("http://record-api.com/"), | |
} | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment