Dynamically reading resources from a file

2019-03-31 14:51发布

I've been using resx files for static strings in order to have a central place for changing them. The problem is that I can't change them after the project is built and deployed.

There are some strings that I would like to change after deployment, without restarting the process (so .config files are out).

It's possible to write code that parses a config file (XML/JSON/YAML/?) efficiently, e.g. caches the result for X seconds or monitors it for changes with FileSystemWatcher, but has something like this already been done?

EDIT: using Json.NET and Rashmi Pandit's pointer to CacheDependency I wrote this JSON parsing class that caches the parsed results until the file is changed:

public class CachingJsonParser
{
    public static CachingJsonParser Create()
    {
        return new CachingJsonParser(
            HttpContext.Current.Server,
            HttpContext.Current.Cache);
    }

    private readonly HttpServerUtility _server;
    private readonly Cache _cache;

    public CachingJsonParser(HttpServerUtility server, Cache cache)
    {
        _server = server;
        _cache = cache;
    }

    public T Parse<T>(string relativePath)
    {
        var cacheKey = "cached_json_file:" + relativePath;
        if (_cache[cacheKey] == null)
        {
            var mappedPath = _server.MapPath(relativePath);
            var json = File.ReadAllText(mappedPath);
            var result = JavaScriptConvert.DeserializeObject(json, typeof(T));
            _cache.Insert(cacheKey, result, new CacheDependency(mappedPath));
        }
        return (T)_cache[cacheKey];
    }
}

Usage

JSON file:

{
    "UserName": "foo",
    "Password": "qwerty"
}

Corresponding data class:

class LoginData
{
    public string UserName { get; set; }
    public string Password { get; set; }
}

Parsing and caching:

var parser = CachingJsonParser.Create();
var data = parser.Parse<LoginData>("~/App_Data/login_data.json");

1条回答
smile是对你的礼貌
2楼-- · 2019-03-31 15:28

You can use xml files and store it in the Cache. You can use CacheDependency to reload the cache when any change is made to the file. Links: CacheDependency: CacheItemUpdateCallback :

In your case your Cache should store an XmlDocument as value

Edit: This is my sample code

protected void Page_Load(object sender, EventArgs e)
{
        XmlDocument permissionsDoc = null;

        if (Cache["Permissions"] == null)
        {
            string path = Server.MapPath("~/XML/Permissions.xml");
            permissionsDoc = new XmlDocument();
            permissionsDoc.Load(Server.MapPath("~/XML/Permissions.xml"));
            Cache.Add("Permissions", permissionsDoc,
                            new CacheDependency(Server.MapPath("~/XML/Permissions.xml")),
                           Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
                    CacheItemPriority.Default, new CacheItemRemovedCallback(ReloadPermissionsCallBack));
        }
        else
        {
            permissionsDoc = (XmlDocument)Cache["Permissions"];
        }
}

private void ReloadPermissionsCallBack(string key, object value, CacheItemRemovedReason reason)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(Server.MapPath("~/XML/Permissions.xml"));
        Cache.Insert("Permissions", doc ,
                            new CacheDependency(Server.MapPath("~/XML/Permissions.xml")),
                           Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
                    CacheItemPriority.Default, new CacheItemRemovedCallback(ReloadPermissionsCallBack));
    }
查看更多
登录 后发表回答