I have a Table that I store All setting in that , it is like below :
public class Setting:IEntity
{
public string Key { get; set; }
public string Value { get; set; }
}
and I have a service like this to update and read Setting Table :
public class SettingService : ISettingService
{
#region Fields
private readonly IUnitOfWork _uow;
private readonly IDbSet<Setting> _settings;
private static readonly ConcurrentDictionary<string, object> _cash = new ConcurrentDictionary<string, object>();
#endregion
#region Methods
#region ctor
public SettingService(IUnitOfWork uow)
{
_uow = uow;
_settings = _uow.Set<Setting>();
if (_cash.IsEmpty)
lock (_cash)
{
if (_cash.IsEmpty)
_settings.ToList().ForEach(item => _cash.TryAdd(item.Key, item.Value));
}
}
#endregion
public T Get<T>() where T : ISetting
{
object value;
var setting = Activator.CreateInstance<T>();
var prefix = typeof(T).Name;
foreach (PropertyInfo item in typeof(T).GetProperties())
{
string key = $"{prefix}.{item.Name}";
_cash.TryGetValue(key, out value);
if (item.PropertyType == typeof(Boolean))
{
bool result;
Boolean.TryParse(value?.ToString(), out result);
item.SetValue(setting, result);
}
else
item.SetValue(setting, value);
}
return setting;
}
public void Set<T>(T model) where T : ISetting
{
var prefix = typeof(T).Name;
Type type = typeof(T);
foreach (PropertyInfo prop in typeof(T).GetProperties())
{
var key = $"{prefix}.{prop.Name}";
var setting = _settings.FirstOrDefault(row => row.Key == key);
var isAddedd = true;
if (setting == null)
{
setting = new Setting { Key = key };
_settings.Add(setting);
_uow.MarkAsAdded(setting);
isAddedd = false;
}
setting.Value = prop.GetValue(model, null)?.ToString() ?? string.Empty;
if (isAddedd)
_uow.MarkAsChanged(setting);
_cash.AddOrUpdate(key, setting.Value, (oldkey, oldValue) => setting.Value);
}
}
#endregion
}
I use this Service Like below :
var data = _settingService.Get<AboutSetting>(); // when I want to featch from db
_settingService.Set<AboutSetting>(aboutUsViewModel);// for update
now I need to Read All Project Setting from project , in some Views I need just some of them like Address , Tel ,...
I have created some Classes Like below :
public static class CompanyConfig
{
private static CompanyInformationSetting _companySettings;
private static ISettingService _settingService;
static CompanyConfig()
{
_settingService = ApplicationObjectFactory.Container.GetInstance<ISettingService>();
_companySettings = _settingService.Get<CompanyInformationSetting>();
}
public static string CompanyAddress
{
get { return _companySettings.Address; }
}
}
and use them in View Like :
<h2> Address : @(CompanyConfig.CompanyAddress) </h2>
Is there a way better than this , does this way bad for Performance ?
Another Way is to change BaseViewPage Like below and set some properties like below :
public class BaseViewPage<TModel> : WebViewPage<TModel>
{
private readonly ISettingService _settingService;
public BaseViewPage()
{
_settingService = ApplicationObjectFactory.Container.GetInstance<ISettingService>();
}
public override void Execute()
{
}
public string CompanyName
{
get { return _settingService.Get<CompanyInformationSetting>("CompanyName"); }
}
public string CompanyPhoneNumber
{
get { return _settingService.Get<CompanyInformationSetting>("PhoneNumber"); }
}
public string CompanyEmail
{
get { return _settingService.Get<CompanyInformationSetting>("Email"); }
}
public string CompanyAddress
{
get { return _settingService.Get<CompanyInformationSetting>("Address"); }
}
}
in this way we dont need to static class and it solves singleton of UnitOfwork