Java Properties implementation for C#
CSharProperties is a set of key value pair that can be saved to a stream or loaded from a stream.
To load the Properties, use the Load
static method from Properties class.
There are three ways to load properties:
var properties = Properties.Load(@"C:\temp\db.properties");
var properties = Properties.Load(stream);
where stream
is a stream for data that contains the properties.
Ex:
var path = Path.GetTempFileName();
var properties = Properties.Load(File.Open(path, FileMode.Open));
File.Open()
return a FileStream
to file specified by path
variable.
You can use a StreamReader
or StringReader
for load the properties.
var content = @"
# This is a comment
host=localhost
port=123
database=test
";
var properties = Properties.Load(new StringReader(content));
Use LoadAsync
for asynchronous operations:
var properties = await Properties.LoadAsync(@"C:\temp\db.properties");
By default, lines beginning with the characters "
, ;
and #
are considered comments and will not be treated as a property. A valid property, by default, follows the template: host=localhost
where host
is the key and localhost
is the value.
Do not use the same key twice, the Properties class will only handle the first key-value pair, the others will be disregarded.
Use the method Get
or the operator []
by passing a string that represents the key
var host = properties["host"]; //or properties.Get("host");
Consult IProperties to view all methods and properties of the class.
Use foreach to iterate through Properties:
foreach (var property in properties)
Console.WriteLine($"{property.Key}={property.Value}");
You can save the properties just by passing the File Path
, or a Stream
, or a Reader
.
properties.Add("database", "test"); // add a property "database" with value of "test"
properties.Save(@"C:\temp\db.properties"); // The file where the properties will be saved
Use SaveAsync
for asynchronous operations:
await Properties.SaveAsync(@"C:\temp\db.properties");
You can customize how the Properties
class handles properties. See the example below.
var content = @"
username:=cooper
#Don"t make this!
password:=1234
#Email will not be captured by the handle
email=cooper@mail
";
bool IsValidLine(string line) =>
!line.StartsWith("#") && line.Contains(":=");
KeyValuePair<string, string> PropertyHandle(string line)
{
var tokens = line.Split(":=");
return tokens.Length == 2
? new KeyValuePair<string, string>(tokens[0].Trim(), tokens[1].Trim())
: new KeyValuePair<string, string>();
}
var properties = PropertiesBuild.NewPropertiesBuild()
.WithValidLineHandle(IsValidLine)
.WithExtractPropertyHandle(PropertyHandle)
.BuildWithTextReader(new StringReader(content));
The IsValidLine
method evaluates whether the line is valid, in this example, a line that does not start with #
and contains :=
is considered valid.
The PropertyHandle
method is responsible for extracting the property of a string, in this example it separates the string by :=
and gets a key-value pair. The property email=cooper@mail
will not be captured by the handler, because according to the IsValidLine
method, it is an invalid line.
Finally, use PropertiesBuilder
to construct the properties using the handlers, in a fluent interface.
You can load and save the properties from Json, Xml and csv.
const string json =
@"[
{
'key': 'host', 'value':'localhost'
},
{
'key': 'database', 'value':'inception'
}
]";
var properties = Properties.LoadFromJson(new StringReader(json));
properties.Add("name", "Yusuf");
properties.Add("role", "chemist");
properties.SaveAsJson(@"C:\temp\properties.json");
The json should follow the following scheme
{
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"required": true
},
"value": {
"type": "string",
"required": true
}
}
}
}
const string xml =
@"<?xml version='1.0' encoding='UTF-8'?>
<properties>
<property key='email' value='[email protected]'/>
</properties>";
var properties = Properties.LoadFromXml(new StringReader(xml));
properties.Add("name", "Yusuf");
properties.Add("role", "chemist");
properties.SaveAsXml(@"C:\temp\properties.xml");
The xml should follow the following scheme
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
attributeFormDefault='unqualified' elementFormDefault='qualified'>
<xs:element name='properties' type='propertiesType' />
<xs:complexType name='propertiesType'>
<xs:sequence>
<xs:element type='propertyType' name='property' maxOccurs='unbounded' minOccurs='0' />
</xs:sequence>
</xs:complexType>
<xs:complexType name='propertyType'>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute type='keyType' name='key' use='required' />
<xs:attribute type='valueType' name='value' use='required' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name='keyType'>
<xs:restriction base='xs:string'>
<xs:minLength value='1' />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name='valueType'>
<xs:restriction base='xs:string'>
<xs:minLength value='0' />
</xs:restriction>
</xs:simpleType>
</xs:schema>
const string csv =
@"email;[email protected]
role;turist";
var properties = Properties.LoadFromCsv(new StringReader(csv));
properties.Add("name", "Yusuf");
properties.Add("role", "chemist");
properties.SaveAsCsv(@"C:\temp\properties.csv");
The delimiter character used is the semicolon (';')
To define your own strategy use the Delegate PropertiesStrategy
PropertiesStrategy myStrategy = content =>
{
//Do yout logic here...
return Of(properties);
};
PropertiesStrategy
receives as argument a string that is the content read from the file (or Stream
) and returns an IProperties
.
Use the LoadFromStrategy
method to load properties based on the created strategy.
var properties = Properties.LoadFromStrategy(myStrategy, file);