CountryData.Globalization
1.0.0
dotnet add package CountryData.Globalization --version 1.0.0
NuGet\Install-Package CountryData.Globalization -Version 1.0.0
<PackageReference Include="CountryData.Globalization" Version="1.0.0" />
<PackageVersion Include="CountryData.Globalization" Version="1.0.0" />
<PackageReference Include="CountryData.Globalization" />
paket add CountryData.Globalization --version 1.0.0
#r "nuget: CountryData.Globalization, 1.0.0"
#:package CountryData.Globalization@1.0.0
#addin nuget:?package=CountryData.Globalization&version=1.0.0
#tool nuget:?package=CountryData.Globalization&version=1.0.0
CountryData.Globalization
A high-performance .NET library providing comprehensive country data, regions, cultures, currencies, and globalization information. Built for international applications with full country/region support.
Features
- High Performance - O(1) dictionary lookups with lazy-loaded caches
- 250+ Countries - Complete ISO 3166-1 country data
- Administrative Regions - States, provinces, territories
- Currency Information - Symbols, codes, names in multiple languages
- Full Globalization - CultureInfo and RegionInfo integration
- Phone Codes - International dialing codes
- Multi-Language - Support for cultures and localized names
- DI Ready - Built-in dependency injection support
- Thread-Safe - All operations are thread-safe
- Zero Dependencies - Lightweight, no external packages
Installation
Option 1: With Dependency Injection Support (Recommended)
Install both the core package and hosting package:
# Core package
dotnet add package CountryData.Globalization
# Hosting package (for DI support)
dotnet add package CountryData.Globalization.Hosting
Package Manager Console:
Install-Package CountryData.Globalization
Install-Package CountryData.Globalization.Hosting
Option 2: Core Package Only
If you don't need dependency injection support:
dotnet add package CountryData.Globalization
Package Manager Console:
Install-Package CountryData.Globalization
Quick Start
Using With Dependency Injection (Recommended)
Step 1: Register the service
// Program.cs
using CountryData.Globalization.Hosting.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Register CountryData services
builder.Services.AddCountryData();
var app = builder.Build();
Step 2: Inject and use
using CountryData.Globalization.Services;
public class CountryController : ControllerBase
{
private readonly ICountryDataProvider _countryProvider;
public CountryController(ICountryDataProvider countryProvider)
{
_countryProvider = countryProvider;
}
[HttpGet("country/{code}")]
public IActionResult GetCountry(string code)
{
var country = _countryProvider.GetCountryByCode(code);
if (country == null) return NotFound();
return Ok(new
{
Name = country.CountryName,
Flag = _countryProvider.GetCountryFlag(code),
Currency = _countryProvider.GetCurrencySymbol(code),
PhoneCode = country.PhoneCode,
IsMetric = _countryProvider.IsMetric(code)
});
}
}
Using Without Dependency Injection
If you're not using DI, create the provider directly:
using CountryData.Globalization.Services;
// Simple - just create it (recommended)
var provider = new CountryDataProvider();
// Use the provider
var country = provider.GetCountryByCode("US");
Console.WriteLine($"{country.CountryName} - {provider.GetCountryFlag("US")}");
// Get regions
var states = provider.GetRegionsByCountryCode("US");
foreach (var state in states)
{
Console.WriteLine($"{state.Name} ({state.ShortCode})");
}
// Get currency info
var symbol = provider.GetCurrencySymbol("US");
Console.WriteLine($"Currency: {symbol}");
Important: Reuse the same provider instance. Don't create new instances repeatedly as it's expensive.
// GOOD - Singleton pattern
public class CountryDataSingleton
{
private static readonly Lazy<ICountryDataProvider> _instance =
new Lazy<ICountryDataProvider>(() => new CountryDataProvider());
public static ICountryDataProvider Instance => _instance.Value;
}
// Usage
var country = CountryDataSingleton.Instance.GetCountryByCode("US");
API Reference
Country Data Methods
| Method | Description | Returns |
|---|---|---|
GetAllCountries() |
Gets all 250+ countries | IEnumerable<Country> |
GetCountryByCode(code) |
Get country by ISO 3166-1 alpha-2 code | Country? |
GetCountryNames() |
Gets all country names | IEnumerable<string> |
GetCountryFlag(code) |
Gets Unicode emoji flag | string |
GetCurrentRegionCountry() |
Gets country for current user's region | Country? |
Example:
var country = provider.GetCountryByCode("US");
var flag = provider.GetCountryFlag("JP");
var allCountries = provider.GetAllCountries();
Phone Code Methods
| Method | Description | Returns |
|---|---|---|
GetPhoneCodeByCountryShortCode(code) |
Get phone code for country | string? |
GetCountriesByPhoneCode(phoneCode) |
Get all countries with phone code | IEnumerable<Country> |
Example:
var phoneCode = provider.GetPhoneCodeByCountryShortCode("GB"); // "+44"
var countries = provider.GetCountriesByPhoneCode("+1"); // US, Canada, etc.
Region Methods
| Method | Description | Returns |
|---|---|---|
GetRegionsByCountryCode(code) |
Get states/provinces/territories | IEnumerable<Region> |
GetCountriesByRegion(regionName) |
Find countries containing region | IEnumerable<Country> |
Example:
var states = provider.GetRegionsByCountryCode("US");
var country = provider.GetCountriesByRegion("California").FirstOrDefault();
Currency Methods
| Method | Description | Returns |
|---|---|---|
GetCurrencySymbol(code) |
Get currency symbol | string? |
GetCurrencyEnglishName(code) |
Get currency English name | string? |
GetCurrencyNativeName(code) |
Get currency native name | string? |
GetCountriesByCurrency(currencyCode) |
Get all countries using currency | IEnumerable<Country> |
Example:
var symbol = provider.GetCurrencySymbol("US"); // "$"
var name = provider.GetCurrencyEnglishName("GB"); // "British Pound"
var euroCountries = provider.GetCountriesByCurrency("EUR");
Culture & Globalization Methods
| Method | Description | Returns |
|---|---|---|
GetCultureInfo(code) |
Get primary CultureInfo | CultureInfo? |
GetAllCulturesForCountry(code) |
Get all cultures for country | IEnumerable<CultureInfo> |
GetSpecificCultureByCountryAndLanguage(country, lang) |
Get specific culture | CultureInfo? |
GetCountriesByCulture(cultureName) |
Get countries by culture | IEnumerable<Country> |
GetCountriesByLanguage(languageCode) |
Get countries by language | IEnumerable<Country> |
Example:
var culture = provider.GetCultureInfo("US"); // en-US culture
var cultures = provider.GetAllCulturesForCountry("CA"); // en-CA, fr-CA
var frenchCA = provider.GetSpecificCultureByCountryAndLanguage("CA", "fr");
RegionInfo Methods
| Method | Description | Returns |
|---|---|---|
GetRegionInfo(code) |
Get .NET RegionInfo | RegionInfo? |
GetDisplayName(code, culture?) |
Get localized country name | string? |
IsMetric(code) |
Check if country uses metric | bool |
GetThreeLetterISORegionName(code) |
Get ISO 3166-1 alpha-3 code | string? |
GetThreeLetterWindowsRegionName(code) |
Get Windows region code | string? |
Example:
var regionInfo = provider.GetRegionInfo("US");
var isMetric = provider.IsMetric("US"); // false
var iso3 = provider.GetThreeLetterISORegionName("US"); // "USA"
Common Usage Examples
Example 1: Country Dropdown for Forms
public class CountryDropdownService
{
private readonly ICountryDataProvider _provider;
public CountryDropdownService(ICountryDataProvider provider)
{
_provider = provider;
}
public List<CountryOption> GetCountryOptions()
{
return _provider.GetAllCountries()
.OrderBy(c => c.CountryName)
.Select(c => new CountryOption
{
Code = c.CountryShortCode,
Name = c.CountryName,
Flag = _provider.GetCountryFlag(c.CountryShortCode)
})
.ToList();
}
}
Example 2: Phone Number Formatting
public class PhoneNumberService
{
private readonly ICountryDataProvider _provider;
public PhoneNumberService(ICountryDataProvider provider)
{
_provider = provider;
}
public string FormatPhoneNumber(string countryCode, string localNumber)
{
var phoneCode = _provider.GetPhoneCodeByCountryShortCode(countryCode);
return $"{phoneCode} {localNumber}";
}
}
// Usage: FormatPhoneNumber("US", "555-1234") returns "+1 555-1234"
Example 3: Address Form with Dynamic Regions
public class AddressFormService
{
private readonly ICountryDataProvider _provider;
public AddressFormService(ICountryDataProvider provider)
{
_provider = provider;
}
public List<RegionOption> GetRegionsForCountry(string countryCode)
{
return _provider.GetRegionsByCountryCode(countryCode)
.Select(r => new RegionOption
{
Code = r.ShortCode,
Name = r.Name
})
.OrderBy(r => r.Name)
.ToList();
}
}
Example 4: Currency Display
public class CurrencyService
{
private readonly ICountryDataProvider _provider;
public CurrencyService(ICountryDataProvider provider)
{
_provider = provider;
}
public CurrencyInfo GetCurrencyInfo(string countryCode)
{
return new CurrencyInfo
{
Symbol = _provider.GetCurrencySymbol(countryCode),
EnglishName = _provider.GetCurrencyEnglishName(countryCode),
NativeName = _provider.GetCurrencyNativeName(countryCode)
};
}
}
Example 5: Multi-Language Support
public class LocalizationService
{
private readonly ICountryDataProvider _provider;
public LocalizationService(ICountryDataProvider provider)
{
_provider = provider;
}
public string GetLocalizedCountryName(string countryCode, string languageCode)
{
var culture = new CultureInfo(languageCode);
return _provider.GetDisplayName(countryCode, culture)
?? _provider.GetCountryByCode(countryCode)?.CountryName
?? "Unknown";
}
}
// Usage:
// GetLocalizedCountryName("JP", "fr-FR") returns "Japon"
// GetLocalizedCountryName("JP", "es-ES") returns "Japón"
Architecture & Performance
Performance Characteristics
| Operation | Time Complexity | Notes |
|---|---|---|
GetCountryByCode |
O(1) | Dictionary lookup |
GetCountriesByPhoneCode |
O(1) | Pre-built index |
GetCountriesByCurrency |
O(1) | Pre-built index |
GetCountriesByLanguage |
O(1) | Pre-built index |
GetAllCountries |
O(1) | Returns cached collection |
GetRegionsByCountryCode |
O(1) | Direct property access |
GetCultureInfo |
O(1) | Pre-built cache |
GetRegionInfo |
O(1) | Pre-built cache |
GetCountriesByRegion |
O(n×m) | Sequential scan - cache if frequently used |
Caching Strategy
All caches use lazy initialization with thread-safe Lazy<T>:
- Country Dictionary - Built at construction (~50ms)
- RegionInfo Cache - Built on first currency/region access (~50-100ms)
- CultureInfo Cache - Built on first culture access (~100-150ms)
- Phone Code Index - Built on first phone query (<10ms)
- Currency Index - Built on first currency query (~50-100ms)
- Language Index - Built on first language query (~100-150ms)
Memory Footprint: ~2-5 MB for all caches combined
Thread Safety
100% Thread-Safe
- Immutable data collections
- Thread-safe lazy initialization via
Lazy<T> - No mutable state
- Safe for concurrent access from multiple threads
- Registered as Singleton by default
Data Models
Country Model
public class Country
{
public string CountryName { get; set; } // "United States"
public string CountryShortCode { get; set; } // "US"
public string PhoneCode { get; set; } // "+1"
public List<Region> Regions { get; set; } // States/Provinces
}
Region Model
public class Region
{
public string Name { get; set; } // "California"
public string? ShortCode { get; set; } // "CA" (optional)
}
Best Practices
Recommended Usage
// GOOD - With DI (Recommended)
builder.Services.AddCountryData();
public class MyService
{
private readonly ICountryDataProvider _provider;
public MyService(ICountryDataProvider provider)
{
_provider = provider;
}
}
// GOOD - Without DI (Simple instantiation)
var provider = new CountryDataProvider();
// GOOD - Without DI (Singleton pattern)
public class CountryDataSingleton
{
private static readonly Lazy<ICountryDataProvider> _instance =
new Lazy<ICountryDataProvider>(() => new CountryDataProvider());
public static ICountryDataProvider Instance => _instance.Value;
}
Anti-Patterns to Avoid
// BAD - Creating new instances repeatedly
foreach (var item in items)
{
var provider = new CountryDataProvider(); // Expensive!
var country = provider.GetCountryByCode(item.Code);
}
// GOOD - Reuse single instance
var provider = new CountryDataProvider();
foreach (var item in items)
{
var country = provider.GetCountryByCode(item.Code);
}
// BAD - Calling GetCountriesByRegion in loops
foreach (var region in regions)
{
var country = provider.GetCountriesByRegion(region).FirstOrDefault(); // O(n×m)!
}
// GOOD - Build your own index for repeated lookups
var regionIndex = provider.GetAllCountries()
.SelectMany(c => c.Regions.Select(r => new { Region = r.Name, Country = c }))
.ToDictionary(x => x.Region, x => x.Country, StringComparer.OrdinalIgnoreCase);
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Country data based on ISO 3166-1 standards
- Culture and region information from .NET
CultureInfoandRegionInfo - Flag emojis using Unicode regional indicator symbols
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Text.Json (>= 8.0.5)
-
net10.0
- No dependencies.
-
net6.0
- System.Text.Json (>= 8.0.5)
-
net8.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on CountryData.Globalization:
| Package | Downloads |
|---|---|
|
CountryData.Globalization.Hosting
Dependency injection extensions for CountryData.Globalization library. Provides seamless integration with Microsoft.Extensions.DependencyInjection for ASP.NET Core and other .NET applications. Includes service registration extensions and lifetime management for ICountryDataProvider. Install this package alongside CountryData.Globalization to enable DI support with AddCountryData() extension method. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 268 | 12/25/2025 |
Initial release v1.0.0:
- 250+ countries with comprehensive ISO 3166-1 data
- Administrative regions (states, provinces, territories)
- Currency information with multi-language support
- Phone codes and international dialing codes
- Full CultureInfo and RegionInfo integration
- O(1) dictionary lookups with lazy-loaded caches
- Thread-safe operations with immutable data collections
- Minimal external dependencies (only System.Text.Json)
- Multi-framework support (.NET Standard 2.0+, .NET 6, 8, 10)
- Works with .NET Framework 4.6.1+, .NET Core 2.0+, Unity, Xamarin
- Built-in dependency injection support via CountryData.Globalization.Hosting package