Project Description
a full function configuration system based on .net

the configuration system contains following functions
1. dynamic load / automatically reload based on dataprovider service <included>
2. load from file / http / ftp or any other stream based storage system <except for file, others need extra code support, but some are already included, such as http>
3. three level structures, config / section / key - value
4. static filter / dynamic filter based on variants input
- static filters are usually hardware and software environments, such as processor count, memory status, os version, refer service version, etc
- dynamic filters are usually request / runtime status, a typical usage is to select different configuration value in http server based on user request ip or browser, etc
5. a set of different filters, include text pattern match, text serial match, int / double interval, int / double comparison, and end users can combine different filters in a single config line
6. high customization, developers can define own character set for configuration key words, and also can add filters to support different scenarios
7. support several different value conversions, and support get configuration list and secondary list

a typical configuration file <produced by test case>, with comments,

;define a dynamic filter, with name as 'spf', and type as 'str-pat' which means string-pattern match filter
spf=str-pat
;'str-pat-cache' means string-pattern match filter with cache, for long string pattern performance improvement, the function is same as string-pattern match filter
spcf=str-pat-cache
;string -> full string match filter
sf=string
;int-int -> integer interval filter
iif=int-int
;str-ser -> string serial filter, each one in the serial matching the variant is match
ssf=str-ser
;dbl-com -> double compare filter
dcf=dbl-com
;start a section
[section]
; try static filters first
;b means build mode
b:unknownbuild$buildmode=unknownbuild
b:debugbuild$buildmode=debugbuild
b:releasebuild$buildmode=releasebuild
; try static filters and int_compare_selector
;pc means processor count
pc:>1$machine_type=normal
pc:>2$machine_type=strange
pc:>3$machine_type=powerful
pc:>7$machine_type=great
pc:<2$machine_type=lowend
;the spf is what we have defined above, when query the configuration with variant <spf = something_p_something_a...ttern1_something>, it can match the follow line, and get value pattern1
key1@spf:*p*a*t*t*e*r*n*1*=pattern1
key1@spf:*p*a*t*t*e*r*n*2*=pattern2
key1@spf:*p*a*t*t*e*r*n*3*=pattern3
key1=key1 no match
key2@spcf:*p*a*t*t*e*r*n*1*=pattern1
key2@spcf:*p*a*t*t*e*r*n*2*=pattern2
key2@spcf:*p*a*t*t*e*r*n*3*=pattern3
key2=key2 no match
key3@sf:string1=string1
key3@sf:string2=string2
key3@sf:string3=string3
key3=key3 no match
;iif is what we have defined above, [0,100) means >=0 but <100, when query configuration with variant <iif = 50>, it can match the follow line, and get value 100
key4@iif:[0,100)=100
key4@iif:[100,200)=200
key4@iif:[200,300)=300
key4=400
key5@ssf:string1,string2,string3=string1,string2,string3
key5@ssf:string4,string5,string6=string4,string5,string6
key5@ssf:string7,string8,string9=string7,string8,string9
key5=string10
;the filters can be combined, such as the follow line, dcf should be > 0 and also < 100.1, users can also use different filters in a single configuration line to make different combinations
key6@dcf:>0&dcf:<100.1=100.1
key6@dcf:>100.1&dcf:<200.2=200.2
key6@dcf:>200.2&dcf:<300.3=300.3
key6@dcf:>300.3&dcf:<400.4=400.4
key6=500.5
write_times=2

following some sample test cases to show how to use the configuration in the production

assert_equal(s()("buildmode"), envs.build)

assert_equal(s()("machine_type"), machine_type())

assert_equal(s()("key1", create_variants("spf", "!pattern1")), "pattern1")
assert_equal(s()("key1", create_variants("spf", "p!attern2")), "pattern2")
assert_equal(s()("key1", create_variants("spf", "pa!ttern3")), "pattern3")
assert_equal(s()("key1", create_variants("spf", "pattern4")), "key1 no match")

assert_equal(s()("key2", create_variants("spcf", "!pattern1")), "pattern1")
assert_equal(s()("key2", create_variants("spcf", "p!attern2")), "pattern2")
assert_equal(s()("key2", create_variants("spcf", "pa!ttern3")), "pattern3")
assert_equal(s()("key2", create_variants("spcf", "pattern4")), "key2 no match")

assert_equal(s()("key3", create_variants("sf", "string1")), "string1")
assert_equal(s()("key3", create_variants("sf", "string2")), "string2")
assert_equal(s()("key3", create_variants("sf", "string3")), "string3")
assert_equal(s()("key3", create_variants("sf", "string4")), "key3 no match")

assert_equal(s()("key4", create_variants("iif", rnd_int(0, 100))).to_int32(), 100)
assert_equal(s()("key4", create_variants("iif", rnd_int(100, 200))).to_int32(), 200)
assert_equal(s()("key4", create_variants("iif", rnd_int(200, 300))).to_int32(), 300)
assert_equal(s()("key4", create_variants("iif", rnd_int(300, 400))).to_int32(), 400)

assert_equal(s()("key5", create_variants("ssf", "string1")), "string1,string2,string3")
assert_equal(s()("key5", create_variants("ssf", "string2")), "string1,string2,string3")
assert_equal(s()("key5", create_variants("ssf", "string3")), "string1,string2,string3")
assert_equal(s()("key5", create_variants("ssf", "string4")), "string4,string5,string6")
assert_equal(s()("key5", create_variants("ssf", "string5")), "string4,string5,string6")
assert_equal(s()("key5", create_variants("ssf", "string6")), "string4,string5,string6")
assert_equal(s()("key5", create_variants("ssf", "string7")), "string7,string8,string9")
assert_equal(s()("key5", create_variants("ssf", "string8")), "string7,string8,string9")
assert_equal(s()("key5", create_variants("ssf", "string9")), "string7,string8,string9")
assert_equal(s()("key5", create_variants("ssf", "string10")), "string10")

assert_equal(s()("key6", create_variants("dcf", rnd_double(0.1, 100.1))).to_double(), 100.1)
assert_equal(s()("key6", create_variants("dcf", rnd_double(100.2, 200.2) + 0.1)).to_double(), 200.2)
assert_equal(s()("key6", create_variants("dcf", rnd_double(200.3, 300.3) + 0.1)).to_double(), 300.3)
assert_equal(s()("key6", create_variants("dcf", rnd_double(300.4, 400.4) + 0.1)).to_double(), 400.4)
assert_equal(s()("key6", create_variants("dcf", rnd_double(400.5, 500.5))).to_double(), 500.5)
assert_equal(s()("key6", create_variants("dcf", rnd_double(-100, -1))).to_double(), 500.5)
assert_equal(s()("key6", create_variants("dcf", 0)).to_double(), 500.5)
assert_equal(s()("key6", create_variants("dcf", 100.1)).to_double(), 500.5)
assert_equal(s()("key6", create_variants("dcf", 200.2)).to_double(), 500.5)
assert_equal(s()("key6", create_variants("dcf", 300.3)).to_double(), 500.5)

assert_equal(s()("write_times").to_int32(), 1)

this configuration system is pretty coupled with other components in the osi project, geminibranch.codeplex.com, so i will leave a non-compilable version in the source code, and an alpha release in the download, i will also update the code / binary here. but for the latest code and binary, please go to the geminibranch.
to use the configuration system, you need to refer osi.service.configuration.dll into your project. and run osi.root.utt.exe configuration_test to make sure you have got a good build.
the default build is against .net 3.5, but i have also added a build-with-4.0.cmd into geminibranch/osi, and finished all the test pass on surface rt <surely you need a jail broken version>, except for several performance cases. so if you need some specific .net version, enlist the code and build from scratch is a good way. after the build, run osi.root.utt.exe * from osi/utt/bin/release | debug to verify basic functionalities.

enjoy, my pleasure if any can help you.

/*******************************
non-commercial use only
*******************************/

thank you

any questions, feel free to drop me a msg to hzj_jie@hotmail.com

Last edited Jun 10, 2013 at 6:00 AM by Hzj_jie, version 7