formosatek/dotliquid — pull request #94 by rdumont (2014-02-18 16:03:33+00:00)
Title: Allow non-global template configuration

Fixes #93. This is what I got:

### Before
```cs
Template.RegisterFilter(typeof(SomeFilters)); // Filter registration
Template.RegisterValueTypeTransformer(type, func); // Value type transformer
Template.RegisterSafeType(type, allowedMembers); // Safe type
Template.RegisterTag("my"); // Tag registration
Template.FileSystem = new MyFileSystem(); // File system

Template.NamingConvention = new SomeNamingConvention();

var template = Template.Parse("the template");
var result = template.Render();
```

### After
```cs
var config = new TemplateConfiguration();
config .RegisterFilter(typeof(SomeFilters)); // Filter registration
config .RegisterValueTypeTransformer(type, func); // Value type transformer
config .RegisterSafeType(type, allowedMembers); // Safe type
config .RegisterTag("my"); // Tag registration
config .FileSystem = new MyFileSystem(); // File system

Template.NamingConvention = new SomeNamingConvention(); // The naming convention was kept global for now, since it could too heavily impact performance and caching

var template = Template.Parse("the template", config);
var result = template.Render();
```

The global methods were all kept so that it doesn't break the interface. Also, the syntax for each configuration was kept the same (including overloads), except for being on the `TemplateConfiguration` instance.

I ran performance tests and no difference was detected on the time taken to run all the tests. Is this good to go?

### Motivation
In case anyone fails to understand the importance of this feature, here is my real-world scenario.

**1. Support different schemas**: I have different schemas of my application running at the same time on the same application. Each schema supports completely different structures for the entities and have tags with different behaviors, although both run on DotLiquid. Therefore, I need to be able to conditionally use a different DotLiquid configuration for each schema.

**2. Validation**: My application supports editing entities through a REST API, so I need to validate their contents so that they don't break at run time. I've found that the best way to do this is by registering fake tags that, instead of fully running their production code, just verify the integrity of their contents and configuration.

**3. Testing**: I don't want my unit tests to depend on a global, static, configuration. If I am testing a class, the test configuration should be as isolated and as close to my tests as possible.