-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathProgram.cs
More file actions
155 lines (126 loc) · 6.14 KB
/
Copy pathProgram.cs
File metadata and controls
155 lines (126 loc) · 6.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using CompaniesHouse;
using CompaniesHouse.Request;
using CompaniesHouse.Response;
using CompaniesHouse.Response.CompanyProfile;
using CompaniesHouse.Response.Search.AllSearch;
using CompaniesHouse.Response.Search.CompanySearch;
using CompaniesHouse.Response.Search.DisqualifiedOfficersSearch;
using CompaniesHouse.Response.Search.OfficerSearch;
using Microsoft.Extensions.DependencyInjection;
using Officers = CompaniesHouse.Response.Officers.Officers;
namespace SampleProject;
class Program
{
// Add your API key from https://developer.company-information.service.gov.uk/
private const string ApiKey = "";
static async Task Main()
{
if (string.IsNullOrEmpty(ApiKey))
{
Console.WriteLine("No API Key found. Please edit Program.cs to add it in.");
return;
}
const string companyNumber = "10440441";
const string nameToSearchFor = "Bigman";
await RunWithDirectClientAsync(nameToSearchFor, companyNumber);
await RunWithDependencyInjectionAsync(companyNumber);
}
/// <summary>
/// The simplest way to use the client: construct <see cref="CompaniesHouseSettings"/> and
/// <see cref="CompaniesHouseClient"/> directly. Prefer the DI path below in ASP.NET Core apps.
/// </summary>
private static async Task RunWithDirectClientAsync(string nameToSearchFor, string companyNumber)
{
var settings = new CompaniesHouseSettings(ApiKey);
using var client = new CompaniesHouseClient(settings);
var searchResult = await client.SearchAllAsync(new SearchAllRequest
{
Query = nameToSearchFor,
StartIndex = 0,
ItemsPerPage = 10
});
DisplaySearchResults(searchResult, nameToSearchFor);
var officersResult = await client.GetOfficersAsync(companyNumber);
DisplayOfficers(officersResult, companyNumber);
}
/// <summary>
/// The recommended way to use the client from an app with an <see cref="IServiceCollection"/>
/// (ASP.NET Core, worker services, etc.).
/// </summary>
private static async Task RunWithDependencyInjectionAsync(string companyNumber)
{
var services = new ServiceCollection();
services.AddCompaniesHouseClient(ApiKey);
await using var provider = services.BuildServiceProvider();
var client = provider.GetRequiredService<ICompaniesHouseClient>();
var result = await client.GetCompanyProfileAsync(companyNumber);
DisplayCompanyProfile(result, companyNumber);
}
private static void DisplaySearchResults(CompaniesHouseResponse<AllSearch> result, string query)
{
Console.WriteLine($"\n----------------------------------------------");
// .Data throws InvalidOperationException on non-success — pattern-match
// when you need to handle error outcomes explicitly.
if (result is not CompaniesHouseResponse<AllSearch>.Success { Data: var data })
{
Console.WriteLine($"Search failed (HTTP {result.StatusCode}).");
return;
}
Console.WriteLine($"Companies matching '{query}':");
foreach (var item in (data.Items ?? []).OfType<Company>())
{
// CompanyStatus is a string-backed value type — it never throws on an
// unrecognised wire value, so we can always describe it safely.
Console.WriteLine($" * {item.Title} — {DescribeCompanyStatus(item.CompanyStatus)}");
}
Console.WriteLine($"\nOfficers matching '{query}':");
foreach (var item in (data.Items ?? []).OfType<Officer>())
Console.WriteLine($" * {item.Title} — {item.Description}");
Console.WriteLine($"\nDisqualified officers matching '{query}':");
foreach (var item in (data.Items ?? []).OfType<DisqualifiedOfficer>())
Console.WriteLine($" * {item.Title}");
}
private static void DisplayOfficers(CompaniesHouseResponse<Officers> result, string companyNumber)
{
Console.WriteLine($"\n----------------------------------------------");
Console.WriteLine($"Officers for {companyNumber}:");
if (result is not CompaniesHouseResponse<Officers>.Success { Data: var data })
{
Console.WriteLine($" Could not retrieve officers (HTTP {result.StatusCode}).");
return;
}
foreach (var officer in data.Items ?? [])
Console.WriteLine($" * {officer.Name}");
}
private static void DisplayCompanyProfile(CompaniesHouseResponse<CompanyProfile> result, string companyNumber)
{
Console.WriteLine($"\n----------------------------------------------");
// Switch expression — the compiler guides you through every outcome.
var summary = result switch
{
CompaniesHouseResponse<CompanyProfile>.Success { Data: var company } =>
$"{company.CompanyName} — {DescribeCompanyStatus(company.CompanyStatus)}",
CompaniesHouseResponse<CompanyProfile>.NotFound =>
$"Company {companyNumber} not found.",
CompaniesHouseResponse<CompanyProfile>.RateLimited { RetryAfter: var delay } =>
$"Rate limited — retry after {delay}.",
CompaniesHouseResponse<CompanyProfile>.Unauthorized =>
"Unauthorized — check your API key.",
CompaniesHouseResponse<CompanyProfile>.ServerError { StatusCode: var code } =>
$"Server error {code} — try again later.",
_ => $"Unexpected response: {result.StatusCode}",
};
Console.WriteLine(summary);
}
/// <summary>
/// String-backed value types never throw for an unrecognised value, so this
/// switch can handle future Companies House statuses gracefully.
/// </summary>
private static string DescribeCompanyStatus(CompanyStatus status) => status switch
{
_ when status == CompanyStatus.Active => "active",
_ when status == CompanyStatus.Dissolved => "dissolved",
_ when status.IsKnown => status.Description ?? status.Value,
_ => $"unknown status ({status.Value})",
};
}