-
-
Notifications
You must be signed in to change notification settings - Fork 105
Migration
For the migration from v2.x to v3 it's most convenient to reference the SmartFormat.NET package.
SmartFormat v3 comes with the following packages:
- SmartFormat.NET - includes all SmartFormat extensions listed below. This is equivalent to the sole v2.x package.
- SmartFormat - The "Core" package
- SmartFormat.Extensions.Newtonsoft.Json - An
ISource
extension forNewtonsoft.Json
variables - SmartFormat.Extensions.System.Text.Json - An
ISource
extension forSystem.Text.Json
variables - SmartFormat.Extensions.Time - The formatter for
DateTime
,DateTimeOffset
andTimeSpan
variables - SmartFormat.Extensions.Xml - Brings the
ISource
extension forXElement
variables, and a formatter forXElement
s
SmartFormat is the core package. It comes with the most frequently used extensions built-in:
i. Source extensions:
GlobalVariablesSource
PersistentVariablesSource
-
StringSource
✔️ -
ListFormatter
(implementingISource
) ✔️ -
DictionarySource
✔️ -
ValueTupleSource
✔️ -
ReflectionSource
✔️ -
DefaultSource
✔️ -
KeyValuePairSource
✔️
ii. Formatter extensions:
-
ListFormatter
(implementingIFormatter
) ✔️ -
PluralLocalizationFormatter
✔️ -
ConditionalFormatter
✔️ -
IsMatchFormatter
✔️ -
NullFormatter
✔️ LocalizationFormatter
TemplateFormatter
-
ChooseFormatter
✔️ -
SubStringFormatter
✔️ -
DefaultFormatter
✔️
Breaking change:
Note that only extensions marked (✔️) are included when calling
Smart.CreateDefaultFormatter(...)
and also when usingSmart.Format(...)
. These default extensions differ from previously included extensions.
Some extensions (like PersistentVariablesSource
and TemplateFormatter
) require configuration to be useful.
Only curly braces {}
can be used forPlaceholder
s in an input string.
In v2.x more than one name could be used. In v3 the formatters have one name.
Formatter | v2.x Names | v3 Name | CanAutoDetect | * |
---|---|---|---|---|
ChooseFormatter | choose, c | choose | Yes | |
ConditionalFormatter | conditional, cond | cond | Yes | |
DefaultFormatter | default, d | d | Yes | |
IsMatchFormatter | ismatch | ismatch | No | |
IsNullFormatter | n/a | isnull | No | |
ListFormatter | list, l | list | Yes | |
LocalizationFormatter | n/a | L | No | |
PluralLocalizationFormatter | plural, p | plural | Yes | |
SubStringFormatter | substr | substr | No | |
TemplateFormatter | template, t | t | No | |
TimeFormatter | timespan, time | time | Yes | * |
XElementFormatter | xelement, xml, x | xml | Yes | * |
Formatters marked with *
are part of separate NuGet packages.
The recommendation is to always use the formatter name. Is is more performant and eases debugging. However, formatters which are flagged with CanAutoDetect
are able to detect whether they can handle a certain value.
It is possible to change the IFormatter.Name
. Example:
// change the name from "cond" to "conditional"
Smart.Default.GetFormatterExtension<ChooseFormatter>().Name = "conditional";
All obsolete element usage creates a compile time error including hints to resolve.
a) Obsolete SmartObjects
have now been removed. Use ValueTupleSource
instead.
b) Class FormatCache
has been removed. Caching is built into class Format
, which is IDisposable
. Usage:
// Auto-dispose or dispose manually
using format = new Parser().ParseFormat("The format string");
c) TimeFormatter
has no constructor with an defaultTwoLetterLanguageName
d) PluralLocalizationFormatter
has no constructor with an defaultTwoLetterLanguageName
e) TimeFormatter
, PluralLocalizationFormatter
, LocalizationFormatter
: Culture is determined in this sequence:
- Get the culture from the
FormattingInfo.FormatterOptions
, e.g.Smart.Format("{0:time(en):noless})
, where "(en)" is the culture option.
- Get the culture from the
IFormatProvider
argument (which may be aCultureInfo
) toSmartFormatter.Format(IFormatProvider, string, object?[])
- The
CultureInfo.CurrentUICulture
e) IFormatters
all have only parameterless constructors. (For any initialization they're implementing the IIntializer
interface.)
f) All custom IFormatter
s must implement the changed interface with properties Name
and CanAutoDetect
g) SystemTime
is now in the SmartFormat.Utilities
namespace
h) JsonSource
has been split into / replaced by NewtonsoftJsonSource
and SystemTextJsonSource
.
i) Interface for IOutput
has changed
a) Parser.ParseFormat()
only has 1 argument for the input string
b) Parser.UseAlternativeEscapeChar()
: Use Settings.StringFormatCompatibility
true | false
c) Parser.UseBraceEscaping()
: Use Settings.StringFormatCompatibility
true | false
Breaking change:
In v3 all
WellKnownExtensionTypes.Sources
andWellKnownExtensionTypes.Formatters
are automatically inserted to the extension list at the place where they usually should be.
Any extension can, however, be inserted to the desired position in the extension list:
SmartFormatter.InsertExtension(int position, IFormatter sourceExtension)
SmartFormatter.InsertExtension(int position, IFormatter formatterExtension)
This can be useful especially when adding your custom extensions. You should call SmartFormatter.InsertExtension(...)
after SmartFormatter.AddExtensions(...)
:
var formatter = new SmartFormatter()
.AddExtensions(new ReflectionSource())
.AddExtensions(new PluralLocalizationFormatter(), new DefaultFormatter())
.InsertExtension(0, new MyCustomFormatter());
For migration pay attention to the following aspects:
a) SmartSettings
have been extended.
b) Don't change settings after the class instance was passed as an argument.
After a "smart class" is instanciated with
SmartSettings
, consider the settings as immutable. Later changes to the settings may or may not take effect.
Reasoning: As long as we're supporting older .Net Frameworks, we can't implement C# 9 Init-Only properties.
// DO
var sf = new SmartFormatter(new SmartSettings { CaseSensitivity = CaseSensitivityType.CaseInsensitive });
// DO NOT
var sf = new SmartFormatter();
sf.Settings.CaseSensitivity = CaseSensitivityType.CaseInsensitive;
The mode can be set with SmartSettings.StringFormatCompatibility
. By default, SmartSettings.StringFormatCompatibility
is false
.
Reasoning: The distinction was necessary because of syntax conflicts between SmartFormat extensions and string.Format
. It brings a more concise and clear set of formatting rules and full string.Format
compatibility even in "edge cases".
a) SmartFormat features mode
- Brings the full set of features implemented in SmartFormat
- Curly braces are escaped the Smart.Format way with
\{
and\}
. - As long as special characters
(){}:\
are escaped with\
, any character is allowed anywhere.
b) string.Format
compatibility mode
- SmartFormat acts as a drop-in replacement
- On top, it allows for named placeholders besides indexed placeholders.
- The
Parser
will not include the formatter name or formatting options. Like withstring.Format
, everything after theSelector
separator (colon) is considered as format specifier. - Curly braces are escaped the
string.Format
way with{{
and}}
. This is the reason for all limitations instring.Format
compatibility mode -
DefaultFormatter
is the only formatter which will be invoked. -
null
will be output asstring.Empty
.
- Syntax, Terminology
- Placeholders and Nesting
- string.Format Compatibility
- Character Literals in Format Strings
- HTML With CSS or JavaScript
- Data Source Extensions
- Default _ DefaultFormatter
- Lists _ ListFormatter
- Choose _ ChooseFormatter
- Condition _ ConditionalFormatter
- Null _ NullFormatter
- SubString _ SubStringFormatter
- RegEx _ IsMatchFormatter
- Pluralization _ PluralLocalizationFormatter
- Localization _ LocalizationFormatter
- Templates _ TemplateFormatter
- TimeSpan _ TimeFormatter
- XML _ XElementFormatter
- Extension Methods
- Home
- Common Pitfalls
- HTML with CSS or JavaScript
- Overview
- Main Features
- Formatters
- Extra Features
- Console and StringBuilder
- TemplateFormatter
- SmartSettings to control Smart.Format behavior
- Additional Info
- License