views:

169

answers:

3

I have an ASP.NET MVC app which depends on a lot of settings (name-value pairs), I am planning to store this information in a database table called SiteSettings. Is there an easy way in which I can get these settings using NHibernate. And what are the best practices when saving settings for a web application. And by settings I mean the settings which control the flow of processes in the web application and which are governed by business rules. These are not the typical connection string kind of settings. I was unable to get much information on the web on this topic. Maybe I am not searching on the right keywords, Any help will be greatly appreciated.

+1  A: 

I can't answer in the context of nhibernate (which I'm not using) or best practices (I came up with this on my own recently). However, it works well for me, and will probably work for you.

I have a table (Biz_Config) in the database to store business preferences. (I've created a web.config section for what I call IT preferences.)

I have a class that is in charge of managing the biz preferences. The constructor grabs the entire table (one row per setting) and copies these into a dictionary, and it has methods to access (such as bizconfig.get("key")) and update this dictionary, also updating the table at the same time. It also has a few shortcut properties for specific dictionary values, especially where the value has to be cast (I have a few important numbers). It works quite well.

In order to be more efficient and not instantiate it every time I need a setting, and also to access it easily from my controllers and views, I created a static class, Globals, that is in charge of getting things out of the session or application variables. For the biz config object, it checks the application variable and, if null, creates a new one. Otherwise it just returns it. Globals is part of my helpers namespace, which is included in my web.config to be available to my views. So I can easily call:

<% Globals.Biz_Config.Get("key") %>

I hope this helps. If you'd like code, I can dig that up for you.

James

James S
Thanks for the answer, I came up with something similar, I'll post it in the original question.
Khaja Minhajuddin
A: 

If you have a set of key/value pairs, you probably want to use a <map>. See the official NHibernate documentation or Ayende's post about 'NHibernate Mapping - <map/>'.

Mufasa
A: 

I have come up with a solution which is quite similar to the one suggested by James. I have an SiteSettingsService class which manages the settings for the whole site, it has a simple dependency on an interface called ISiteServiceRepository. This might not be the most elegant solution, But it is working perfectly for me. I have also configured the SiteSettingsService class as a Singleton using StructureMap. So, it saves me unnecessary instantiantion every time I need any settings.

//ISiteServiceRepository, an implementation of this uses NHibernate to do just two things
//i)Get all the settings, ii)Persist all the settings
using System.Collections.Generic;
using Cosmicvent.Mcwa.Core.Domain.Model;

namespace Cosmicvent.Mcwa.Core.Domain {
    public interface ISiteServiceRepository {
        IList<Setting> GetSettings();
        void PersistSettings(IDictionary<string, string> settings);
    }
}

//The main SiteSettingsService class depends on the ISiteServiceRepository
using System;
using System.Collections.Generic;
using Cosmicvent.Mcwa.Core.Domain;
using Cosmicvent.Mcwa.Core.Domain.Model;

namespace Cosmicvent.Mcwa.Core.Services {
    public class SiteSettingsService : ISiteSettingsService {

        private readonly ISiteServiceRepository _siteServiceRepository;
        private IDictionary<string, string> _settings;

        public SiteSettingsService(ISiteServiceRepository siteServiceRepository) {
            _siteServiceRepository = siteServiceRepository;
            //Fill up the settings
            HydrateSettings();
        }


        public int ActiveDegreeId {
            get {
                return int.Parse(GetValue("Active_Degree_Id"));
            }
        }

        public string SiteTitle {
            get { return GetValue("Site_Title"); }
        }

        public decimal CounsellingFee {
            get { return decimal.Parse(GetValue("Counselling_Fee")); }
        }

        public decimal TuitionFee {
            get { return decimal.Parse(GetValue("Tuition_Fee")); }
        }

        public decimal RegistrationFee {
            get { return decimal.Parse(GetValue("Registration_Fee")); }
        }

        public void UpdateSetting(string setting, string value) {
            if (!string.IsNullOrEmpty(setting) && !string.IsNullOrEmpty(value)) {
                SetValue(setting, value);
                PersistSettings();
            }
        }

        //Helper methods
        private void HydrateSettings() {
            _settings = new Dictionary<string, string>();
            IList<Setting> siteRepoSettings = _siteServiceRepository.GetSettings();
            if (siteRepoSettings == null) {
                throw new ArgumentException("Site Settings Repository returned a null dictionary");
            }
            foreach (Setting setting in siteRepoSettings) {
                _settings.Add(setting.Name.ToUpper(), setting.Value);
            }
        }

        private string GetValue(string key) {
            key = key.ToUpper();
            if (_settings == null) {
                throw new NullReferenceException("The Site Settings object is Null");
            }
            if (!_settings.ContainsKey(key)) {
                throw new KeyNotFoundException(string.Format("The site setting {0} was not found", key));
            }
            return _settings[key];
        }

        private void SetValue(string key, string value) {
            key = key.ToUpper();
            if (_settings == null) {
                throw new NullReferenceException("The Site Settings object is Null");
            }
            if (!_settings.ContainsKey(key)) {
                throw new KeyNotFoundException(string.Format("The site setting {0} was not found", key));
            }

            _settings[key] = value;
        }

        private void PersistSettings() {
            _siteServiceRepository.PersistSettings(_settings);
        }

    }
}

Hope this helps future developers facing similar problems. Any suggestions for improving this are more than welcome.

Khaja Minhajuddin