4

TLDR;

I need to extract the string value of the parameter of all calls to the index operator of Microsoft.Extensions.Localization.IStringLocalizer in my .NET code. Actually I also need the full name of the enclosing class.

Caveat: The above also includes my ASP.NET Core MVC razor views.

Basically my need is quite similar to the "Find all references" functionality in Visual Studio.

Why and other thoughts

The reason is that we appreciate the development flow using IStringLocalizer without the need to actually create resources. In addition we have replaced the usage of resource files with a database store using Damien Bods AspNetCoreLocalization.

This allows us to have business experts do all the translations (1) without access to the file system of the webserver, and (2) from a nice interface that we provide, and (3) independently from the development cycle. However, in order to have the business experts know which texts exist - and thus need translation - we need to extract all usages of the IStringLocalizer (and IViewStringLocalizor) index operator.

Based on this article, I've partly managed to extract the information from the loaded assemblies.

My major problems are:

  • My code is based on SDILReader which is quite old and no longer maintained and apparently has a number of issues (with newer CIL?)
  • How am I going to extract usage in razor views which are JIT compiled at runtime?
  • I prefer to extract the data at latest at deployment time, but preferably at commit or CI build time
  • Can Roslyn help fulfilling my need?
  • Have I overlooked any tools or alternative approaches?
  • I prefer a solution that isn't to vulnerable to future .NET framework/runtimes versions or new C# features

Any ideas or pointers are most welcome :-) Thanks

Bjarke M
  • 211
  • 2
  • 9
  • What about creating a wrapper around it? – Maritim Aug 31 '17 at 13:05
  • I don't think there is anything you can do at the interface level. Any interception or wrapping would have to happen at the class the implements it. – Bradley Uffner Aug 31 '17 at 13:06
  • 2
    Roslyn will definitely be the way to approach this, since you can use it to analyze your code for this purpose. I’m not sure how this will work inside Razor though, you might need to add some special handling for Razor views then. – poke Aug 31 '17 at 13:07
  • How, deep do you want the analysis to go? Are you looking for just method invocations with constants or could the the values be dynamic? – Titian Cernicova-Dragomir Aug 31 '17 at 14:17
  • Thanks for input. Based on your comments and my own research I'm currently leaning towards a Roslyn based solution. I'm trying to build a little command line tool to use in my CI build. – Bjarke M Sep 01 '17 at 12:42
  • @bradley and Maritim, I'm not talking about runtime interception but about static code analysis. – Bjarke M Sep 01 '17 at 12:45
  • @poke, I agree but have to check about razor. – Bjarke M Sep 01 '17 at 12:46
  • @titian, I need no more than indexer invocation with const strings - due to convention and coding style :-) – Bjarke M Sep 01 '17 at 12:46
  • 1
    @BjarkeM That makes things a lot simpler when analyzing the IL – Titian Cernicova-Dragomir Sep 01 '17 at 12:49

1 Answers1

1

In order of your bulet points:

  1. I analyzed IL code using Mono Reflection It says it works with .NET 4 and seems to be somewhat maintained (last release was 2016)
  2. Razor views are compiled to C# classes and you can do this at build time using the ASP.NET Compiler (this is also useful to avoid the slow first hit load times) Once the pages are compiled you can analize the resulting classes.
  3. Extracting at commit may take a long time (building the views takes a while if they are any) I would do it on the CI server.
  4. For C# Roslyn is definitely an option but I don't think it can help you with the razor view, but I am not 100% sure of this.
  5. I do not know of any tools that would help you with this task, but I don't know for sure
  6. Analyzing IL is prone to break if the IL changes, but that would be true of a C# code analyzer as well, and IL changes a lot less then C#.

If you need help with the symbolic execution of the code, I could post a simple symbolic execution method that could track things such constants in local variables or on the execution stack.

Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357