If you want to contribute to this repo, please read the contributing guide first.
How to setup your development environment:
- Install the latest version of Visual Studio
- Install the version of .NET SDK specified in the global.json file. Currently 2.2.101
- Use the solution
Meziantou.Framework.sln
- You can run unit tests using the Test explorer in Visual Studio or the command line
dotnet test
You can also use Visual Studio Code but you won't be able to run the WPF samples.
Lots of extensions methods and utilities
// IO Extensions
IOUtilities.PathCreateDirectory(@"c:\test\file.txt")
IOUtilities.MakeRelativePath(root: @"c:\test", path: @"c:\temp\file.txt") // ..\temp\file.txt
IOUtilities.ToValidFileName("tes/t.txt") // tes_x47_t.txt
// String Extensions
"test".EqualsIgnoreCase("Test")
"test".ContainsIgoreCase("ES")
"Tést".RemoveDiacritics() // Test
// Throttle / Debounce
action.Throttle(TimeSpan.FromMilliseconds(300));
action.Debounce(TimeSpan.FromMilliseconds(300));
// Slugs
Slug.Create("My super blog post") // my-super-blog-post
// And many more extensions/utilities
A universal converter that supports lots of conversion.
ConvertUtilities.ChangeType("42", defaultValue: 0)
ConvertUtilities.ChangeType("Value1, 2", defaultValue: MyEnum.Unknown)
CSV reader and writer.
var reader = new CsvReader(textReader);
reader.HasHeaderRow = true;
CsvRow row;
while((row = (await reader.ReadRowAsync())) != null)
{
row[0]; // Get value by index
row["column1"] // Get value by column name
}
var writer = new CsvWriter(sw);
await writer.WriteRowAsync("A", "B");
await writer.BeginRowAsync();
await writer.WriteValueAsync("C");
await writer.WriteValueAsync("D");
Recurrence Rule parser, and ICS generator
var rrule = RecurrenceRule.Parse("FREQ=DAILY;COUNT=3");
var startDate = new DateTime(1997, 09, 02, 09, 00, 00);
var occurrences = rrule.GetNextOccurrences(startDate);
// 1997-09-02 09:00
// 1997-09-03 09:00
// 1997-09-04 09:00
Get the perceived type of a file: Text, Audio, Video, Document, Application, etc.
var perceived = Perceived.GetPerceivedType(".avi");
Assert.AreEqual(PerceivedType.Video, perceived.PerceivedType);
CredentialManager.WriteCredential("ApplicationName", "username", "Pa$$w0rd", CredentialPersistence.Session);
var cred = CredentialManager.ReadCredential("ApplicationName");
Assert.AreEqual("username", cred.UserName);
Assert.AreEqual("Pa$$w0rd", cred.Password);
CredentialManager.DeleteCredential("ApplicationName");
Template template = new Template();
template.Load("Hello <%=Name%>!");
template.AddArgument("Name", typeof(string));
string result = template.Run("Meziantou"); // result= "Hello Meziantou!"
Extensions for Templating to support the html format: Encoding text, url or attribute. For email, it extracts the list of cid.
var template = new HtmlEmailTemplate();
template.Load("<head><title>{{@begin section title}}Hello {{# Name }}{{@end section}}!</title></head>" +
"<body>{{#html "Here's an image"}} <img src=\"{{cid sample.png}}\" /></body>");
template.AddArgument("Name", typeof(string));
string result = template.Run("Meziantou", out var metadata);
Assert.AreEqual("<head><title>Hello Meziantou!</title></head><body>Here's an image <img src=\"cid:sample.png\"/></body>", result);
Assert.AreEqual("Hello Meziantou", metadata.Title);
Assert.AreEqual("sample.png", metadata.ContentIdentifiers[0]);