Asp.net mvc ASP.NET MVC ViewHelpers和依赖项注入

Asp.net mvc ASP.NET MVC ViewHelpers和依赖项注入,asp.net-mvc,dependency-injection,ninject,view-helpers,onion-architecture,Asp.net Mvc,Dependency Injection,Ninject,View Helpers,Onion Architecture,我想创建一个ViewHelper来本地化我的ASP.NET MVC应用程序。大概是这样的: public class Translator { private readonly ITranslationRepository _repo; public Translator(ITranslationRepository repo) { _repo = repo; } public static string Translate(Transl

我想创建一个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);
    }
}
<p>@Translator.Translate(TranslationEnum.WelcomeMessage)</p>
(Razor)视图中的用法如下所示:

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);
    }
}
<p>@Translator.Translate(TranslationEnum.WelcomeMessage)</p>
@Translator.Translate(TranslationEnum.WelcomeMessage)

现在的问题当然是,我无法使
Translate
方法保持静态,因为我需要访问实例变量
\u repo


如何将存储库注入ViewHelper,以便在上述视图中使用它?

首先,您的设计意图是错误的,因为它违反了单一责任原则。为什么翻译器依赖于存储库

第二,为什么你需要翻译,你可以使用asp.net全球化? 我们不应该重新发明轮子

第三,所有html助手都是静态的扩展方法

所以我的建议是,如果您必须使用translator,请重构translator类,将存储库与之分离,然后从那里创建扩展方法

或者你可以使用全球化,一开始听起来很可怕,但相信我,这并不像看上去那么难

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);
    }
}

首先,您的设计意图是错误的,因为它违反了单一责任原则。为什么翻译器依赖于存储库

第二,为什么你需要翻译,你可以使用asp.net全球化? 我们不应该重新发明轮子

第三,所有html助手都是静态的扩展方法

所以我的建议是,如果您必须使用translator,请重构translator类,将存储库与之分离,然后从那里创建扩展方法

或者你可以使用全球化,一开始听起来很可怕,但相信我,这并不像看上去那么难

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);
    }
}

首先,您的设计意图是错误的,因为它违反了单一责任原则。为什么翻译器依赖于存储库

第二,为什么你需要翻译,你可以使用asp.net全球化? 我们不应该重新发明轮子

第三,所有html助手都是静态的扩展方法

所以我的建议是,如果您必须使用translator,请重构translator类,将存储库与之分离,然后从那里创建扩展方法

或者你可以使用全球化,一开始听起来很可怕,但相信我,这并不像看上去那么难

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);
    }
}

首先,您的设计意图是错误的,因为它违反了单一责任原则。为什么翻译器依赖于存储库

第二,为什么你需要翻译,你可以使用asp.net全球化? 我们不应该重新发明轮子

第三,所有html助手都是静态的扩展方法

所以我的建议是,如果您必须使用translator,请重构translator类,将存储库与之分离,然后从那里创建扩展方法

或者你可以使用全球化,一开始听起来很可怕,但相信我,这并不像看上去那么难

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);
    }
}

视图的职责只是将从控制器返回的数据转换为HTML结构。视图很难(甚至不可能)自动测试,所以最好是让它们尽可能保持沉默

不要在视图中使用
转换器
,而是将其插入控制器,让控制器调用
转换器
。这解决了一系列问题:

  • 它使视图保持简单
  • 它提高了可维护性
  • 它提高了可测试性
  • 它提高了对象图的可验证性(因为您不会依赖于静态方法调用或服务定位器反模式)
长话短说,将属性添加到控制器的视图模型并将其返回到视图。例如:

公共类HomeController:控制器{
专用只读ITranslator翻译器;
公共家庭控制器(ITranslator转换器){
this.translator=translator
}
公共行动结果索引(){
此.View(新的HomeViewModel){
WelcomeMessage=this.translator.Translate(TranslationEnum.WelcomeMessage)
});
}
}
您的视图可以如下所示:

@model HomeViewModel

<p>@Model.WelcomeMessage</p>
@model HomeViewModel
@Model.welcome消息


视图的职责只是将从控制器返回的数据转换为HTML结构。视图很难(甚至不可能)自动测试,所以最好是让它们尽可能保持沉默

不要在视图中使用
转换器
,而是将其插入控制器,让控制器调用
转换器
。这解决了一系列问题:

  • 它使视图保持简单
  • 它提高了可维护性
  • 它提高了可测试性
  • 它提高了对象图的可验证性(因为您不会依赖于静态方法调用或服务定位器反模式)
长话短说,将属性添加到控制器的视图模型并将其返回到视图。例如:

公共类HomeController:控制器{
专用只读ITranslator翻译器;
公共家庭控制器(ITranslator转换器){
this.translator=translator
}
公共行动结果索引(){
此.View(新的HomeViewModel){
WelcomeMessage=this.translator.Translate(TranslationEnum.WelcomeMessage)
});
}
}
您的视图可以如下所示:

@model HomeViewModel

<p>@Model.WelcomeMessage</p>
@model HomeViewModel
@Model.welcome消息


视图的职责只是将从控制器返回的数据转换为HTML结构。视图很难(甚至不可能)自动测试,所以最好是让它们尽可能保持沉默

不要在视图中使用
转换器
,而是将其插入控制器,让控制器