Project Description provides a remote configuration and control network to the .Net apps in your enterprise. App configuration becomes centralised and live/runtime changes are pushed to each application - no restart required to pick up the change. Cache control commands can also be sent!


What problem does it solve?

In short - application configuration and cache invalidation. Any .Net application (, Console, Windows Service, Winform, WPF, etc) using Castle/Windsor (other IoC containers to be supported later) can use to manage its configuration and local cache store.

In an enterprise platform there are often many apps sharing the same configuration values, usually stored in an isolated xml configuration file that is updated with the correct environment values at build/deploy time. Each app would have a copy of these configuration property files and an update means updating all instances. Ultimately you have multiple isolated xml files containing duplicates of the same configuration value - and you have to manage all of these instances.

Similarly with local caches - each application may utilise a local cache that has a (stale) copy of a piece of data - how do you manage invalidation when the actual master piece of data is changed by an update?


What does it do?

Trollr.Net provides a radical new way to manage your application configuration! With Trollr.Net no configuration values are deployed with an application, instead they are stored in a central configuration store; this also means they can be shared across applications. Each application loads its required configuration at startup and then trollr will manage any changes over the lifecycle of the application - updates to the central configuration store are sent to each application as they happen without needing to restart the application.
  • Out goes the numerous xml files.
  • In comes a single centralised configuration store with notification changes pushed to each application in realtime.
  • Provides a bi-directional command channel between each application and a central configuration and control service.
  • Applications can subscribe for configuration and cache updates and will receive notification when any happen.
  • No restart/recycle of the application is required to pick up the configuration change - the new value is immediately available to the running code.
  • Central config & control service continuously checks for updates and pushes them to each subscribed application as they are committed to a central configuration store (currently SqlServer is supported).
  • Overrides for specific configuration properties can be applied at either an application or machine or more finer, targeting a single machine/app combo.
  • Future Feature Configuration changes can also be scheduled - a start/end date can be attached to a configuration value and this is automatically pushed to the subscribed applications at the correct time. Eg: You could schedule an elevation in logging level for a specific part of the day.

How does it work?

It's based around a central windows service that manages configuration and cache changes. A WCF pub/sub mechanism allows your app to "pull" it's configuration from a central configuration store at startup - a reciprocal channel is then be used to push runtime configuration changes to all subscribed applications along with commands to invalidate any in-process caches when data state has changed.

PLEASE READ The initial release of utilises the capability of the Castle/Windsor IoC container in order to work. So for you to use your application must use Castle/Windsor for DI/IoC - if it doesn't then cannot be used. Now the good news! The important aspect that leverages from Castle/Windsor is interception - any IoC container that has equivalent functionality can be used. is designed to allow other IoC containers to be plugged in - it initially ships with a Castle/Windsor adapter but I'm sure in time other container wrappers will be implemented or if you are up for a challenge write an adapter for your container (and even contribute it back to the project for big kudos). It's written against the .Net 4.0 framework in case you were wondering...


When your application starts installs a WCF net.tcp servicehost that can be called by the central service; it will also contact the central service with details of your application including the callback address of the servicehost and a list of configuration values required. This list of configuration values is gathered by the trollr infrastructure using reflection - all you need do is mark any object requiring trollr configuration with a special trollr interface and each public property on the object needs a trollr attribute (this allows you to override the property name with a more descriptive configuration label for it). The central service gathers the current configuration values for the properties requested and replies to the application which in turn stores these in the system.web.cache (HttpCache) for super fast local access by trollr.

The central service is also responsible for managing the distribution of configuration changes. When a enabled client starts up and requests its configuration values the central service automatically subscribes the client - a record is created in a "subscriptions" table and this holds the machine, app id and callback address (uri) of the WCF service running on the client. The central service is continually monitoring the configuration store for changes and when it detects a change it will attempt to cross-reference subscribers to ensure that only the applicable ones are notified of the change.

There is only one special requirement (that hopefully shouldn't be a barrier for you adopting trollr to manage your configuration) - the object that contains the properties to manage must be a dependency of another object in your IoC container. The reason for this is that trollr works by creating a proxy to the object and intercepting the property calls - in order for this to work there must be an object to proxy in the first place. This is actually how I would setup my objects/components for IoC anyway but it might be different to how you do things. Here is an example (taken from the demo project code) to demonstrate this approach and hopefully you will agree that a) it's a good approach in general and b) that creates almost no "disruption" in using it.

1. Here is our business component interface and implementation. Notice the BusinessOperationConfig property - this is a dependency that will automatically be handled by the IoC container. This property is to our component that holds all the configuration properties this component needs; note this could also be created as a constructor parameter.
public interface IBusinessOperation
    string DoSomethingImportant();

public class BusinessOperation : IBusinessOperation
    // This will be injected automatically by the IoC container
    // and contains all the properties we want to 
    // control the configuration of
    public BusinessOperationConfig Config { get; set; }

    public string DoSomethingImportant()
        return string.Format("Url:={0}; Action:={1}", Config.Url, Config.Action);

2. Here is our configuration component. Notice it implements the ITrollrConfigurable interface
and that each auto property has a TrollrConfigured attribute and is virtual (this is a requirement for proxy/interception).
public class BusinessOperationConfig : ITrollrConfigurable
    [TrollrConfigured(Name = "ModifiedUrl")]
    public virtual string Url { get; set; }

    public virtual string Action { get; set; }        

3. Bootstrap your application's Windsor container and load the business component into it against the IBusinessOperation interface. So far, so normal, however here is where kicks in. In a normal application you would also have to register the dependent BusinessOperationConfig configuration component in order for the container to inject it into our BusinessOperation implementation. With you don't have to register the BusinessOperationConfig component - it will take care of this for us so cutting down on container configuration.
myInstance =  new WindsorContainer()
    // register only the business component - no need to register
    // the configuration component as Trollr will do this for us
    .Configure(c => c.LifeStyle.Transient));

4. Start It will register the BusinessOperationConfig and all other ITrollrConfigurable components for you; it scans all assemblies loaded into the AppDomain to discover all ITrollrConfigurable components and does two things...
  1. Creates a proxy for each ITrollrConfigurable component and registers it into your IoC container. When your application asks to resolve the IBusinessOperation component the container will inject the proxy into the BusinessOperation instead of the actual BusinessOperationConfig component. This proxy provides the interception hook for to take control over the property value.
  2. The public properties of each ITrollrConfigurable component are scanned and any that are decorated with the TrollrConfigured attribute are added to a list. Once scanning is complete this list is sent to the central server which will reply with the current configuration values.
The parameters required are...
  1. The application name - a descriptive name to identify this application within the configuration store.
  2. The tcp port to host the service within your application.
  3. Container.Current is a helper property to your Windsor Container instance (IWindsorContainer).
Core.Trollr.Run("Test-Console", 17002, Container.Current);

5. That's it as far as your application and the impact has on your codebase. All that remains is for the the central configuration service to be installed and loaded with your configuration values. Read on to understand this service better.

Central Configuration Service

This is implemented as a windows service and utilises another of my open-source projects MonitorWang to provide the service infrastructure; server functionality is simply a MonitorWang plug-in. In order to get the central service up and running you will need to download and install MonitorWang first, then drop in the plug-in. The complete soup-to-nuts instructions to get up and running are here.

Last edited Feb 10, 2011 at 11:13 AM by jimbobdog, version 31