In the following program, in order to get resource strings i am using _localizer["About Title"] where "About Title" is a magic string. How to avoid using strings like this? Is there any strongly typed way?
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Localization.StarterWeb.Controllers
{
[Route("api/[controller]")]
public class AboutController : Controller
{
private readonly IStringLocalizer<AboutController> _localizer;
public AboutController(IStringLocalizer<AboutController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get()
{
return _localizer["About Title"];
}
}
}
If you're trying to avoid using a hardcoded string (key) to lookup the localization conversion you could create a LocalizationKeys
class that contains the lookup keys for you. You could then leverage the C# 6 nameof
operator. This would help alleviate the concern of "magic strings".
public static class LocalizationKeys
{
public const string AboutTitle = nameof(AboutTitle); // Note: this is "AboutTitle"
// ... other keys here
}
Then you could consume it wherever. One of the benefits are that since this is a member of the class, if the key changes you can use common refactoring tools to safely replace all the references to it rather than trying to do a global string replace on the "magic string". Another benefit is you'd get to use intellisense when accessing the class. I suppose one could consider this "strongly typed".
You'd consume it as such:
[Route("api/[controller]")]
public class AboutController : Controller
{
private readonly IStringLocalizer<AboutController> _localizer;
public AboutController(IStringLocalizer<AboutController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get()
{
return _localizer[LocalizationKeys.AboutTitle];
}
}
If you really want to get fancy with C# 6 you can also utilize a static using. This will allow you to reference the members of the type you specify. Finally, for simple "single line" returns, we can make them expression bodies. For example:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using static Localization.StarterWeb.LocalizationKeys; // Note: static keyword
namespace Localization.StarterWeb.Controllers
{
[Route("api/[controller]")]
public class AboutController : Controller
{
private readonly IStringLocalizer<AboutController> _localizer;
public AboutController(IStringLocalizer<AboutController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get() => _localizer[AboutTitle]; // Note: omission of qualifier
}
}