我想创建一个ViewHelper来本地化我的ASP.NET MVC应用程序。像这样:
public class Translator
{
private readonly ITranslationRepository _repo;
public Translator(ITranslationRepository repo)
{
_repo = repo;
}
public static string Translate(TranslationEnum translationEnum)
{
return _repo.GetTranslation(translationEnum, Session.LanguageId);
}
}
(Razor)视图中的用法如下所示:
<p>@Translator.Translate(TranslationEnum.WelcomeMessage)</p>
现在问题是,我无法使Translate
方法成为静态,因为我需要访问实例变量_repo
。
如何将存储库注入ViewHelper中,以便在上面的视图中使用它?
答案 0 :(得分:3)
视图的职责只是将从控制器返回的数据转换为HTML结构。自动测试很难(不可能),所以最好是让它们尽可能地保持愚蠢。
不要在视图中使用Translator
,而是将其注入控制器并让控制器调用Translator
。这解决了一系列问题:
简而言之,将属性添加到控制器的视图模型并将其返回到视图。例如:
public class HomeController : Controller {
private readonly ITranslator translator;
public HomeController(ITranslator translator) {
this.translator = translator
}
public ActionResult Index() {
this.View(new HomeViewModel {
WelcomeMessage = this.translator.Translate(TranslationEnum.WelcomeMessage)
});
}
}
您的观点如下:
@model HomeViewModel
<p>@Model.WelcomeMessage</p>
答案 1 :(得分:0)
首先,您的设计意图是错误的,因为它违反了单一的责任原则。为什么翻译依赖于存储库?
其次,为什么需要翻译,你可以使用asp.net全球化? click me我们不应该重新发明轮子。
第三,所有html助手都是必须是静态的扩展方法。
所以我的建议是,如果你必须使用翻译器,请重构翻译器类,将存储库与其分离,然后从那里创建扩展方法。
或者你可以使用全球化,开始时听起来很糟糕,但相信我并不像它看起来那么难。
public class Translator
{
private static ITranslationRepository _repo;
public static ITranslationRepository Repo
{
get { /*check null here before return*/ return _repo; } set { _repo = Repo; }
}
public Translator()
{
}
public static string Translate(TranslationEnum translationEnum)
{
return _repo.GetTranslation(translationEnum, Session.LanguageId);
}
}