Miguel Moura
Miguel Moura

Reputation: 39434

Load file data into static class, load file into cache or other option?

I am localizing an ASP.NET MVC 5 application using PO files.

I created an HTTP module to intersect responses of type html, javascript, etc:

public class I18NModule : IHttpModule {

    private Regex _types;

    public I18NModule() {

      _types = new Regex(@"^(?:(?:(?:text|application)/(?:plain|html|xml|javascript|x-javascript|json|x-json))(?:\s*;.*)?)$");

    } // I18NModule

    public void Init(HttpApplication application) {
      application.ReleaseRequestState += OnReleaseRequestState;
    } // Init

    public void Dispose() {
    } // Dispose

    private void OnReleaseRequestState(Object sender, EventArgs e) {
      HttpContextBase context = new HttpContextWrapper(HttpContext.Current);
      if (_types != null && _types.Match(context.Response.ContentType).Success) 
        context.Response.Filter = new I18NFilter(context, context.Response.Filter, _service);
    } // Handle

} // I18NModule

Then I have an I18NFilter as follows:

public class I18NFilter : MemoryStream {

    private II18NNuggetService _service;
    protected HttpContextBase _context;
    private MemoryStream _buffer = new MemoryStream(); 
    protected Stream _output; 

    public I18NFilter(HttpContextBase context, Stream output, II18NNuggetService service) {
      _context = context;
      _output = output;
      _service = service;
    } // I18NFilter

    public override void Write(Byte[] buffer, Int32 offset, Int32 count) {
      _buffer.Write(buffer, offset, count);
    } // Write

    public override void Flush() {
      Encoding encoding = _context.Response.ContentEncoding;
      Byte[] buffer = _buffer.GetBuffer();
      String entity = encoding.GetString(buffer, 0, (Int32)_buffer.Length);
      _buffer.Dispose();
      _buffer = null;
      buffer = null;

      *USE SERVICE TO LOAD PO FILE AND PROCESS IT*

      buffer = encoding.GetBytes(entity);
      encoding = null;
      Int32 count = buffer.Length;
      _output.Write(buffer, 0, count);
      _output.Flush();
    } // Flush

} // I18NFilter

When I intersect the response I look for strings as [[[some text]]]. "some text" will be the key which I will look for in the PO file for current thread language.

So I need to load the PO file for the current language, process it, and find the strings that need to be translated.

My problem is performance ... Should I load the entire file in a static class?

Should I load the file in each request and use CacheDependency?

How should I do this?

Upvotes: 0

Views: 966

Answers (1)

Justin Helgerson
Justin Helgerson

Reputation: 25531

Since this is an HTTP application I would take advantage of HttpRuntime.Cache. Here is an example of how it could be used to minimize the performance cost:

public override void Flush() {
    ...
    var fileContents = GetLanguageFileContents();
    ...
}

private string GetLanguageFileContents(string languageName) {
    if (HttpRuntime.Cache[languageName] != null)
    {
        //Just pull it from memory!
        return (string)HttpRuntime.Cache[languageName];
    }
    else
    {
        //Take the IO hit  :(
        var fileContents = ReadFileFromDiskOrDatabase();
        //Store the data in memory to avoid future IO hits  :)
        HttpRuntime.Cache[languageName] = fileContents;
        return fileContents;
    }
}

Upvotes: 1

Related Questions