Introduction
Learn how to provide assistance for allowing other developers to specify formatting of objects from your code no different than Intellisense in Microsoft Visual Studio.
Applies to
Product | Version |
---|---|
.NET | 7,8,9 |
Samples overview
Using Entity Framework Core (but not limited to EF Core), read data using the following model.
public partial class BirthDay
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateOnly? BirthDate { get; set; }
// computed column
public int? YearsOld { get; set; }
}
To produce the following output.
This is done by hardcoding each properties format e.g. D2, MM/dd/yyyy
Using the following code.
public static async Task Conventional()
{
await using var context = new Context();
var list = await context.BirthDays.ToListAsync();
foreach (var item in list)
{
// line broken for readability
Debug.WriteLine($"{item.Id,-5:D2}" +
$"{item.FirstName,-15}" +
$"{item.LastName,-15}" +
$"{item.BirthDate!.Value,-12:MM/dd/yyyy}" +
$"{item.YearsOld!.Value:D3}");
}
}
StringSyntaxAttribute Class
The StringSyntaxAttribute class provides the ability to allow the caller to a method to specify their own format e.g. rather than D2, D5 etc.
Revised code from the first code sample.
StringSyntax(NumericFormat) means to present number formats.
StringSyntax(DateOnlyFormat) means to present DateOnly formats.
public static async Task Syntax(
[StringSyntax(NumericFormat)] string iDFormat,
[StringSyntax(DateOnlyFormat)] string dateFormat,
[StringSyntax(NumericFormat)] string ageFormat)
{
await using var context = new Context();
var list = await context.BirthDays.ToListAsync();
foreach (var item in list)
{
// line broken for readability
Debug.WriteLine($"{item.Id.ToString(iDFormat),-5}" +
$"{item.FirstName,-15}" +
$"{item.LastName,-15}" +
$"{item.BirthDate!.Value.ToString(dateFormat),-12}" +
$"{item.YearsOld!.Value.ToString(ageFormat)}");
}
}
Other formats supported
- DateTimeFormat
- EnumFormat
- GuidFormat
- Json
- Regex
- TimeOnlyFormat
- TimeSpanFormat
- Uri
- Xml
Create your own
Another idea is to setup formatting from a source such as appsettings.json
In the following example the formats are in appsettings.json.
{
"ApplicationSetting": {
"IdentifierFormat": "D2",
"DateOnlyFormat": "MM/dd/yyyy",
"AgeFormat": "D3"
}
}
Using the following model.
public class ApplicationSetting
{
public string IdentifierFormat { get; set; }
public string AgeFormat { get; set; }
public string DateOnlyFormat { get; set; }
}
In the provided code sample the following is used to get our formats.
public static ServiceCollection ConfigureServices()
{
static void ConfigureService(IServiceCollection services)
{
services.Configure<ConnectionStrings>(Config.Configuration.JsonRoot()
.GetSection(nameof(ConnectionStrings)));
services.Configure<EntityConfiguration>(Config.Configuration.JsonRoot()
.GetSection(nameof(EntityConfiguration)));
services.Configure<ApplicationSetting>(Config.Configuration.JsonRoot()
.GetSection(nameof(ApplicationSetting)));
services.AddTransient<SetupServices>();
}
var services = new ServiceCollection();
ConfigureService(services);
return services;
}
Create out own Attribute to store multiple formats.
internal class Samples
{
/// <summary>
/// Get formats from appsettings.json, see <see cref="SetupServices"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public class AppSyntaxAttribute : Attribute
{
public static string IdentifierFormat = FormatSettings.Instance.Items.IdentifierFormat;
public static string AgeFormat = FormatSettings.Instance.Items.AgeFormat;
public static string DateOnlyFormat = FormatSettings.Instance.Items.DateOnlyFormat;
}
public async Task SpecialSyntax([AppSyntax()] string numbers = "")
{
var idFormat = AppSyntaxAttribute.IdentifierFormat;
var dateFormat = AppSyntaxAttribute.DateOnlyFormat;
var yearsOldFormat = AppSyntaxAttribute.AgeFormat;
await using var context = new Context();
var list = await context.BirthDays.ToListAsync();
foreach (var item in list)
{
// line broken for readability
Debug.WriteLine($"{item.Id.ToString(idFormat),-5}" +
$"{item.FirstName,-15}" +
$"{item.LastName,-15}" +
$"{item.BirthDate!.Value.ToString(dateFormat),-12}" +
$"{item.YearsOld!.Value.ToString(yearsOldFormat)}");
}
}
}
Summary
Code has been presented to provide a single developer or a team of developers to have intellisense for method parameters.