This file is a running history of fixes and improvements from version 7.0 onwards. Changes are documented for the newest version first. Within each version, classes are covered in alphabetical order.
Version 7.18 is a maintenance release, which affects only one library,
WizardWrx.Core.dll, which got rushed into production without sufficient
testing. This release got the substantially more careful testing that I prefer
to give to everything. The companion NuGet package went out when I built the
release configuration of the whole library set.
With this release, the two most actively updated libraries, WizardWrx.Core.dll
and WizardWrx.Common.dll, automatically update their respective NuGet packages
when a new release build is created. Other libraries will eventually get the
same treatment, but these two went first, because I needed to update them and
immediately pull both into another project, and they receive by far the most
frequent updates. At present, these are the only two projects that have NuGet
package generation and publication built into their .csproj files.
Since its inception, this class has always listed the file version reported by the FileVersion object in the System.Diagnostics namespace. Beginning with this version, the assembly version reported by the Assembly class in the System.Reflection namespace is also given, and each is labeled with its source.
Override the default ToString method, so that it returns a formatted string
containing the values of its two members (properties), so that they appear in a
watch window without requring the object to be expanded.
A new ReplaceEscapedTabsInResourceString extension method undoes the escaped TAB
characters that go into a string that contains TAB characters when it is pasted
into the string resource editor to become part of a .resx file.
ShowFileDetails is a new FileInfo extension method that returns a formatted
string containing user-selected properties of a file.
Significantly simplify CreateFormatString and CreateLastToken by way of a much
more efficient algorithm that consumes much less memory and CPU time.
The XML comments attached to integer constant DECIMAL_DIGITS_DEFAULT contained
a plain ASCII table that caused it to display incorrectly in the DocFX page that
was generated from it. Though this change affected the source code, forcing a
new build, the generated assembly is otherwise identical to its predecessor.
The additions revolve around a new method to apply pairs of strings, each composed of an original and a replacement value, to a string. Two versions exist, one which provides a place to stash the array, while the other is an extension method on the System.String class. The two new resource strings are incidental, though both are employed in the unlikely event that you feed an invalid array to the new methods.
Since they are intended to be used everywhere, the string resources are marked as Public. This release demonstrates the value of that, with additions as follows.
| Name | Value | Comment |
|---|---|---|
| MSG_VALUE_IS_INVALID | invalid | Use this string to report that the value of a variable is invalid. |
| MSG_VALUE_IS_VALID | valid | Use this string to report that the value of a variable is valid. |
This new class exposes one method, ApplyFixups, which applies pairs of strings
comprised of an original and its replacement to a string. The array of string
pairs is stored in the instance for reuse.
This established string extension class gets a new method, ApplyFixups, which
applies pairs of strings comprised of an original and its replacement to a
string. Unlike the StringFixups class, which has a place to store them, this
method takes the array as its argument.
Only the product build number changed, from 210 to 211, to account for the migration of all subsidiary projects to NuGet packages.
Each of the 10 libraries is in its own like-named NuGet package. For example,
the Nuget package that contains WizardWrx.Core.dll is WizardWrx.Core. The
following table lists the packages, along with their version numbers.
| Library | Package Name | Version |
|---|---|---|
| WizardWrx.ASCIIInfo.dll | WizardWrx.ASCIIInfo | 7.1.83.29298 |
| WizardWrx.Common.dll | WizardWrx.Common | 7.15.102.41891 |
| WizardWrx.FormatStringEngine.dll | WizardWrx.FormatStringEngine | 7.15.162.826 |
| WizardWrx.Core.dll | WizardWrx.Core | 7.15.153.2428 |
| WizardWrx.AssemblyUtils.dll | WizardWrx.AssemblyUtils | 7.15.114.34743 |
| WizardWrx.DiagnosticInfo.dll | WizardWrx.DiagnosticInfo | 7.15.1 |
| WizardWrx.MoreMath.dll | WizardWrx.MoreMath | 7.15.1.36803 |
| WizardWrx.ConsoleStreams.dll | WizardWrx.ConsoleStreams | 7.15.191.37663 |
| WizardWrx.EmbeddedTextFile.dll | WizardWrx.EmbeddedTextFile | 7.15.90.42197 |
| WizardWrx.DLLConfigurationManager.dll | WizardWrx.DLLConfigurationManager | 7.15.211 |
In addition to substituting NuGet packages throughout, a handful of errata in the XML documentation got fixed. Otherwise, the code is unchanged from the code that was first marked as version 7.15.
Following is a summary of changes made in version 7.15, released Sunday, 28 April 2019.
Define the following single-character strings:
| Name | Value |
|---|---|
| COLON | ":" |
| COMMA | "," |
| DOUBLE_QUOTE | """ |
| FULL_STOP | "." |
| HYPHEN | "-" |
| SEMICOLON | ";" |
| SINGLE_QUOTE | "'" |
| TAB_CHAR | "\t" |
| UNDERSCORE_CHAR | "_" |
These are for constructing string constants. Though equivalent character
constants were defined in WizardWrx.SpecialCharacters long ago, they are useless
for constructing a string constant, which must be composed entirely of other
string constants. Constants cannot derive their values by calling the ToString
method on a character constant.
XML comments attached to the character constants that correspond to the new string constants listed above get new cross references to the corresponding string constant. There are no new constants.
Supplement the PropsSetFromConfig property with a PropsLeftAtDefault property.
This class also benefits from changes made in its base class,
WizardWrx.AssemblyLocatorBase, defined in WizardWrx.Core.dll.
-
Replace the
ConfigMessagestring property with theRecoveredConfigurationExceptionslist. -
Replace the properties collection enumeration with the much more efficient dictionary lookup.
Though it is omitted from the change log, a significant benefit is that these changes, along with others deeper in the code, eliminated a harmless null reference exception that was being silently thrown, caught, and handled. That exception is addressed by adding an overlooked null reference test that prevents the code that would have executed from doing so.
EnumerateMissingConfigurationValues is an instance method that reports
configuration values that are defined, but are missing from the configuration
file. All such properties have hard coded default values. The report is returned
as a formatted string that can be logged to the system console or the event log,
or displayed on a message box.
This class also benefits from changes made in its base class,
WizardWrx.AssemblyLocatorBase, defined in WizardWrx.Core.dll.
This new class, derived from System.Exception, provides a mechanism for
recording an exception without actually throwing it. The recorded exception is a
reasonbly faithful reproduction of the System.Exception that you would get if
you reported it by throwing.
The UnconfiguredDLLSettings class implements the Singleton pattern, because its operation relies on there being exactly one instance. It uses a generic Dictionary keyed by a concatenation of the configuration file name and configuration key name to store a complete list of configuration settings that have their hard coded default values, because there are no explicit settings in the configuration file.
Each UnconfiguredSetting object stores the name of the configuration file, the
name of the configuration setting, and its value in three string properties, of
which the first two comprise the index.
The design is not quite ideal, since the key relies on the ToString method
override, since there is no separately named computer property to expose it. I
anticipate resolving this inefficiency soon. Meanwhile, it functions correctly,
and correcting this deficiency can be accomplished without breaking anything.
WizardWrx.DLLConfigurationManager.ExceptionLogger (defined in WizardWrx.DLLConfigurationManager.dll)
Define s_strSettingsOmittedFromConfigFile as a static string property that
returns a message that lists the properties that are absent from the DLL
configuration file, along with their hard coded default values.
As always, the test program has been amended to demonstrate the new features, including the new string constants and the improved plumbing.
Following is a summary of changes made in version 7.14, released Monday, 24 December 2018.
Define the constants listed in the following table.
| Name | Value |
|---|---|
| TICKS_PER_1_WEEK | 6,048,000,000,000 |
| TICKS_PER_1_DAY | 864,000,000,000 |
| TICKS_PER_23_59_59 | 863,990,000,000 |
| TICKS_PER_23_59_00 | 863,400,000,000 |
| TICKS_PER_1_HOUR | 36,000,000,000 |
| TICKS_PER_1_MINUTE | 600,000,000 |
| TICKS_PER_1_SECOND | 10,000,000 |
| TICKS_PER_1_MILLISECOND | 10,000 |
BREAKING CHANGE TICKS_PER_SECOND is correctly described in the XML
comment, but its numerical value was off by a factor of one thousand. This is
corrected by making its value equal to TICKS_PER_1_SECOND.
These tick values were computed by a custom class in a lab project that I use to test ideas and algorithms, and the constants were derived therefrom by Excel worksheet formulas.
Add a new GetTheSingleInstance overload that takes only the OptionFlags
parameter.
Class WizardWrx.ClassAndMethodDiagnosticInfo (defined in WizardWrx.ClassAndMethodDiagnosticInfo.dll)
This is a new class and a new library that leverages new features in the version
of System.Runtime.CompilerServices that ships with version 4.5 of the Microsoft
.NET Framework to return the name of the calling method without resorting to
Reflection.
For ease of access, the single class, ClassAndMethodDiagnosticInfo, is in the
WizardWrx namespace. Since it requires a higher version of the framework
than almost everything else, it went into a dedicated library, so that the others
can retain their original target, version 3.5 Client Profile.
This class is relocated from WizardWrx.Core.dll to a dedicated library for two reasons.
1 Since it uses ClassAndMethodDiagnosticInfo methods in its exception reports,
its target framework must be at least 4.5.
2 Since its methods perform mathematical operations that can cause arithmetic overflows that should be caught and reported, it must be compiled with arithmetic checking enabled.
New functions in this version are a set of DecimalShift routines that perform
left and right decimal shift operations. While the required math is technically
trivial, it is easy to get wrong. Hence, in the same spirit that motivated the
WizardWrx.BitMath classes, a recent need for a decimal shift motivated creation
of these decimal shift routines.
Following is a summary of changes made in version 7.13, released Monday, 10 December 2018.
Define EXACTLY_ONE_HUNDRED_MILLION_LONG, to meet an immediate requirement, along
with EXACTLY_ONE_HUNDRED_THOUSAND and EXACTLY_ONE_HUNDRED_MILLION, to more or
less complete the set of powers of ten from two to 9. All powers of ten in that
range sove one (ten million), for which there is no immediate need, are now
covered.
Change Under Conideration Earlier today, I discovered that multiplying a
pair of regular integers (type System.Int32) that you expect to yield a long
that is too big to fit in a System.Int32 yields a large negative number, rather
than throwing an exception. While enabling arithmetic overflow checking in the
advanced compiler settings might elicit exceptions, such an exception would be
an unaacceptable outcome. However, if one of the operands is a long integer (a
System.Int64), the compiler generates code that causes the operation to be
performed with long integer operands, yielding the desired outcome. Since
neither outcome of using 32-bit integers in multiplications that yield a 64-bit
product is optimal, it may be worthwhile to define these constants as
long integers, although doing so would almost certainly force arithmatic
operations that would not otherwise be implemented as 64-bit math operations to
be implemented as long integer operations. While this makes little difference in
a 64-bit execution environment, it adds unnecessary complexity to operations
that take place in a 32-bit context. Regardless, scratch storage requirments,
most likely occupying space on the stack, would essentially double for all math
operations that used these constants, and all 64-bit math operations that run in
a 32-bit logical machine require many extra machine instructions, even for the
simplest operations.
For the time being, there are two constants, EXACTLY_ONE_HUNDRED_MILLION_LONG
and EXACTLY_ONE_HUNDRED_MILLION, which differ only with respect to their types.
Following is a summary of changes made in version 7.12, released Friday, 23 November 2018.
This class gets a refinement of one of its initial methods, plus two new ones that are closely related to it.
-
IsEvenlyDivisibleByAnyIntegerprevents theDivideByZeroExceptionthat would otherwise arise when a divisor of zero is fed to the second operand of the modulus operator. To preent it, the divisor is tested, and anArugmentExceptionexception takes its place. Since theArugmentExceptionarises in user code, the exception message displays the dividend that was fed into the failed method, to aid consumers in identifying the source of the exception when the calling code discards the stack trace. -
Modis the logical companion toIsEvenlyDivisibleByAnyInteger, offered as syntactic sugar, andRemainder, analogous to theIEEERemainderMath method, are synonymns.
All three methods share a common message template, which went into the embedded string resources in the library to facilitate localization.
Following is a summary of changes made in version 7.11, released Saturday, 17 November 2018.
-
BREAKING CHANGE Rename
EXACTLY_ONE_NUNDREDtoEXACTLY_ONE_HUNDREDto correct a misspelling that prevented me finding it. -
Correct the value of
EXACTLY_TEN_THOUSAND, which I discovered was returning one million. -
Define overlooked constants
EXACTLY_TEN(10) andEVENLY_DIVISIBLE(0), the latter handy for use with the modulus operator.
-
Define
IntegerToHexStroverloads that omit the second and third arguments, substituting common defaults for the missing arguments. -
Change
FormatStatusCodeto use the simplified first overload, shortening its stack frame and call setup requirments.
This class makes its debut, with the following static methods.
-
IsEvenlyDivisibleByAnyInteger, defined twice, to accept integer and long inputs. -
IsGregorianLeapYearimplements the Gregorian leap year algorithm correctly. -
IsValidGregorianYearreturns TRUE when given a number is a valid year in the Gregorian calendar.
-
RenderEvenWhenNullrepresents a null reference as a localizable string literal,MSG_OBJECT_REFERENCE_IS_NULL, defined inWizardwrx.Common.Properties.Resources. -
EnumFromStringis a generic method that attempts to convert a string to a member of any enumeration. The enumeration type is inferred from the return type specified in the method call.
The documentation of this library is re-phrased so that everything is in active voice. The code is unchanged.
Following is a list of changes made in version 7.1, released Sunday, 07 October 2018.
Incorporate CapitalizeWords, which I created and tested as part of the Great
Eastern Energy DataFarmer application.
Define SPACE_CHAR for use when only a string will do, and cross reference the
new constant to its antecedent, SpecialCharacters.SPACE_CHAR.
Override ToString to render all three representations (printable string,
hexadecimal, then decimal, in that order), and define static method
DisplayCharacterInfo to provide that service for an arbitrary character
without instantiating ASCII_Character_Display_Table.
Incidental changes included in this commit are as follows.
-
SpecialCharacters.cs got a cross reference to
SpecialStrings.SPACE_CHAR. -
ProductAssemblyInfo.cs reflects the new library version number, 7.1.
-
AssemblyInfo.cs in all individual libraries reflects the new library version number and a build number increment.
-
Resources.resx in DLLServicesTestStand has the following new strings
IDS_ASCII_CHARACTER_INFO,IDS_ASCII_TABLE_CHARACTER_PROPERTIES, andIDS_ASCII_TABLE_ENUMERATION. -
ClassTestMap.TXT in DLLServicesTestStand defines two new unit test method mappings. Note, too, that the terminal newline is gone. This is by design, to eliminate 4 bytes from the embedded resource that contribute nothing to its usability.
-
FormatStringParsing_Drills.cs in DLLServicesTestStand, which also exercises
WizardWrx.ASCIIInfo.dll, which was developed and deployed concurrently, exercises the new static method for displaying a printable version of any ASCII character, along with its numerical value, expressed in both decimal and hexadecimal notation. -
NewClassTests_20140914.cs in DLLServicesTestStand incorporates overlooked unit tests of the entire
SpecialStringsclass. -
Program.cs in DLLServicesTestStand calls the new methods that went into class
NewClassTests_20140914.