Enterprise Library : Configuration Part 1.1.1 – Storage Providers


First of all, I am amazed at the community that has already built up around Enterprise Library.  You guys are awesome.  For any of you going I will be at Vs Live next week and any one that wants to have some face time come to the Enterprise Library talk given by Ron Jacobs and I will be hanging around afterwards.  If you have any feedback, want to dive into some code, etc., please come by and see me. 

Important Stuff Here
To work with what I am going to talk about you will need to patch Enterprise Library with patch 1462 (don’t worry we hadn’t patched it 1462 times, this is just our internal build number) found here (http://www.gotdotnet.com/workspaces/workspace.aspx?id=295a464a-6072-4e25-94e2-91be63527327).  I found this problem when writing this post, so this is why it has taken me a while to get it out .

As I talked about before, a storage provider is an extension point that allows you to store your meta-configuration in another physical store.  The following interfaces are involved in creating a storage provider : IStorageProviderReader, IStorageProviderWriter, IConfigurationChangeWatcherFactory, and IConfigurationChangeWatcher. I will try to explain each one of these without regurgitating the existing documentation.

IStorageProviderReader
The IStorageProviderReader interface allows you to create a read only provider to your storage. We wanted to separate this out so if you have requirements that configuration is only read at runtime and written at development / deployment time you could separate this functionality and support the scenario.  For example, you want to make sure you don’t have code out there arbitrarily changing configuration information in the file, you only want to give this support to operators in your data center.

IStorageProviderWriter
The IStorageProviderWriter interface is the inverse of the IStorageProviderReader interface. Now I doubt you would implement a write only storage, but hey what do I know?

IConfigurationChangeWatcherFactory
The IConfiguraitonChangeWatcherFactory is interesting.  We needed / wanted a way for the storage provider to notify us when the underlying storage changed externally (heck we know when you do it through code ).  We wanted to separate the the responsibility of reading and wring to storage from watching for changes, so we created the interface and had the IStorageProviderReader interface implement it so when we find your IStorageProviderReader, we can query for an IConfigurationChangeWatcherFactory to get your implementation for an IConfigurationChangeWatcher.  (Did I just say query… oh my COM days are bleeding through ).

IConfigurationChangeWatcher
The IConfigurationChangeWatcher is an interface that allows you to create an object that will watch for external changes in your configuration store.  You will always need to create one and return one or an exception will be thrown.  This “feature” will probably be changed in the future.  So if you don’t want / need an IConfigurationChangeWatcher, then you should create a null one that would look something like this: 

   1:  public class NullConfigurationChangeWatcher : IConfigurationChangeWatcher
   2:  {
   3:      public NullConfigurationChangeWatcher()
   4:      {
   5:      }
   6:   
   7:      public event ConfigurationChangedEventHandler ConfigurationChanged;
   8:      
   9:      public void StartWatching(){}
  10:   
  11:      public void StopWatching(){}
  12:      
  13:      public string SectionName
  14:      {
  15:          get { return "MySectionName"; }
  16:      }
  17:   
  18:      public void Dispose(){}
  19:  }
 

In the section name you would return your configuration section name.

Enterprise Library Implementation of Storage Providers
For our implementation of a Storage Provider, we chose to store each configuration in a separate file. Our thinking was that in a server side scenario you don’t want to touch the app.config file especially web.config so the whole ASP AppDomain does not tear down.  The Storage Provider is implemented in the XmlFileStorageProvider.  This guy just reads the Xml as a node to pass back up the chain. Now since we create strongly typed object graphs, we use the XmlSerializer in our transformer so we can serialize and deserialize the XmlNode. More on this in the next post.

New Storage Providers
Now for what you all have been waiting for… a new storage provider.  Since Peter has been bugging me since he started working on Enterprise Library for writing all the configuration to the single application configuration file, I finally did it. The main detail you need to know is that this storage provider will not work with the designer.  I will be posting a designer for this storage provider sometime in the next few days.  To see it work, run the unit tests and then look at the configuration file in the output directory to see it’s output.

Download the sample from the release section in the GotDotNet workspace Releases section.

Now playing: Zero 7In the Waiting Line

Comments (15)

  1. Great Stuff Scott,

    A few little things:

    Most of us will have run the installer and so our folder structure will be different to yours for the solution file, so assuming people will put the "Extensions" folder into "C:Program FilesMicrosoft Enterprise Librarysrc" then the path to the Common and Configuration Projects in the solution file become "..CommonCommon.csproj" and "..ConfigurationConfiguration.csproj" respectively.

    Could we have the missing Readme.txt file?

    I took some advice from the original documentation and strong named the enterprise library dlls and put them into the GAC, now I find I cannot run the NUnit tests. Do you have any advice to get around this one? The test complains that it cannot load "Microsoft.Practices.EnterpriseLibrary.Configuration.Tests.ConfigurationData"

    Cheers… Steve

  2. Serge Shimanovsky says:

    Scott,

    I would like to see the REAL samle of how to use the config. block with MY SQL DB storage. I understand there is no default provider neither transformer (if needed?) to accomplish this. Interesting to see the example of the finished solution on this.

    Or may be you can point me out to the place where I can get one?

    Thanks, Serge

  3. Mario Puskaric says:

    Scott,

    Question is same as from Serge,

    when would we see some SQL database Storage Provider and SQL Serializer Transformer?

    Thanks

  4. Senkwe says:

    So, am I correct in assuming that a change (made dynamically) to my web applications configuration file will end up restarting the webserver even though the actual configuration changes are made to a file external to the one in "bin"?

    On our current project, we’re creating databases on the fly through a web interface and therefore need to store the details of these new DB’s in config files.So it’s not feasible to restart the webserver each time a config change is made as everybody logged in will lose their work. I hope I’m wrong. If not, is there an easy way out or do I have to roll up my sleeves and hack away at the source?

    Thanks.

  5. Senkwe says:

    Sorry I meant the web app needs to be restarted, not the webserver.

  6. You can save changes to external configuraiton (it is not in the external xml file if you are using the out of box support) without it restarting the web app. As long you don’t update the meta-data configuration, you will not get a restart.

  7. JayG says:

    Hey Scotty,

    A wee question, I am new to EntLib, I have strong named the EntLib assemblies, but when I try to open the (web.config in my case) config files using the EntLib Configuration editor it doesn’t load it properly. Also if I have App Setting elements sitting in my config it comes up with an error box. How to tackle this?

    Help appreciated.

    BTW: G8 stuff with EntLib

    Cheers

  8. Yang says:

    There is something I don’t like in EntLib ConfigAB. It’s the thread polling of ConfigurationChangeFileWatcher class. See my blog at:

    http://spaces.msn.com/members/yangcao88/Blog/cns!1ppRXnKxUiSr5Bh0faV-l1PQ!117.entry

  9. Olorin says:

    I’m in line with Serge and Mario :)

    I tried to extend the Config block with my own MySqlStorageProvider and MySqlTransformer but, so far, I’ve failed.

    admittedly, I’m new to the EL, so, maybe what I’d really need would be an explanation of what is *striclty* necessary in a StorageProvider child and in a Transformer child.

    Furthermore, I’m interested to see if you’d use the Data Access block to make a provider and transformer dealing with a database (I’d think so, but, heck, what do I know?)

    Thanks for all the great work so far,

    F.O.R.

  10. JayG says:

    My Web Method is calling an ASP.NET assembly. This assembly is using Enterprise Library – Data Access Blocks. When I consume my web method it gives me an error indicating that web service project does not have definition to dataconfiguration.config file.

    Why is there a requirement for defining the EntLib configuration information in the web service project’s web.config file?

    Plz clarify.

    Cheers

  11. Hi JayG,

    You don’t have to define your data in web.config, what is defined there is the meta-data. The error sounds like you defined the meta-data in the web.config file, but you the configuration system cannot find the file containing the external configuration named "dataconfiguration.config". If you look in the web.config file under the section "dataConfiguration" you should see a path which is the file that the configuration system is looking for. Make sure this path is reachable by the configuraiton system and you should be fine.

    scott

  12. Alexander says:

    Hello,

    I have tried to strong name the EL but it is not working for me. Let me explain the process I have followed so you can tell me what I am doing wrong.

    1. I create the snk file

    2. I open the Enterprise Library Solucion.

    3. Add the URL to the snk file to all the Assemblies info

    4. When I compile I get errors, specially in the Design projects

    Other thing I did was to only sign some of the App Blocks but when I do this and open, lets say, a previous generated web.config it doesn’t open correctly. It just shows the "Application" node in the configuration tool.

    So my concrete question is:

    How do I strong name the EL?

    I really apprreaciate your help on this.

    Alex.