【问题标题】:Simple Injector - Custom WebViewPage简单注入器 - 自定义 WebViewPage
【发布时间】:2016-08-01 17:21:22
【问题描述】:

我有一个使用翻译的小应用程序(目前)。 我的翻译服务叫Translator(ITranslator)。

我的问题是我不想在每个控制器(返回一个视图)中检索这个类,所以我可以在我的视图中使用它。

我的 ListService 也有类似的问题(我在其中存储了所有 SelectListItem 列表)。

CustomWebViewPage

public abstract class CustomViewPage<TModel> : WebViewPage<TModel>
{
    readonly IScriptFactory scriptFactory;
    readonly IMembership membership;
    readonly IListService listService;
    readonly ITranslator translator;

    IHtmlString path;

    public IMembership Membership { get { return this.membership; } }
    public override IPrincipal User { get { return this.membership.User; } }
    public IListService Lists { get { return this.listService; } }
    public ITranslator Translator { get { return this.translator; } }

    public CustomViewPage(IScriptFactory scriptFactory, IMembership membership,
        IListService listService, ITranslator translator)
    {
        this.scriptFactory = scriptFactory;
        this.membership = membership;
        this.listService = listService;
        this.translator = translator;
    }

    public IHtmlString OwnScriptsPath
    {
        get { return path ?? (path = scriptFactory.Create(this.Html).ToHtmlString()); }
    }

    private string languageHtml =
        "<meta name=\"language\" content=\"" + membership.CurrentLanguage + "\">";
    public IHtmlString MetaLanguage { get { return MvcHtmlString.Create(languageHtml); } }
}

及用法:

<div>
   @Lists.GetNationalities(Model.NationalityId)
</div>

但是,在运行应用程序时出现以下错误:

'[NAMESPACE].CustomViewPage' 不包含构造函数 需要 0 个参数

但是如果我创建第二个构造函数,Simple-Injector 会抛出错误,因为它不支持多个构造函数。

我怎样才能实现我想要的,或者不可能?

编辑

完整的堆栈跟踪

c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET 文件\vs\520dfaa2\f5e4578c\App_Web_index.cshtml.a8d08dba.jtlk7fxz.0.cs(40): 错误 CS1729:“SportsHub.SDK.Infrastructure.CustomViewPage” 不包含带 0 个参数的构造函数

at System.Web.Compilation.AssemblyBuilder.Compile()
at System.Web.Compilation.BuildProvidersCompiler.PerformBuild()
at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)
at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound)    at System.Web.Compilation.BuildManager.GetCompiledType(VirtualPath virtualPath)
at System.Web.Compilation.BuildManager.GetCompiledType(String virtualPath)
at System.Web.Mvc.BuildManagerWrapper.System.Web.Mvc.IBuildManager.GetCompiledType(String virtualPath)
at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)

编辑 2

正如@StriplingWarrior 和@Steven 建议的那样,我使用了属性注入,但它似乎不适用于WebViewPage

我在一个服务上测试,属性注入成功,但是在这个类中,属性是null

PS:我使用 get;set; 公开了这些属性

新视图页面:

public abstract class CustomViewPage<TModel> : WebViewPage<TModel>
{
    [Inject]
    public IScriptFactory scriptFactory { get; set; }
    [Inject]
    public IMembership membership { get; set; }
    [Inject]
    public IListService listService { get; set; }
    [Inject]
    public ITranslator translator { get; set; }

    IHtmlString scriptsPath;
    public IHtmlString OwnScriptsPath()
    {
        if (scriptsPath == null)
        {
            scriptsPath = scriptFactory.Create(this.Html).ToHtmlString();
        }
        return scriptsPath;
    }

    /// <summary>
    /// Renders the current user language with a meta tag
    /// </summary>
    public IHtmlString MetaLanguage()
    {
        return MvcHtmlString.Create("<meta name=\"language\" content=\"" + membership.CurrentLanguage + "\">");
    }

对于InjectAttribute,我关注了以下documents

【问题讨论】:

  • 这可能是相关的:stackoverflow.com/questions/7656195/…
  • @StriplingWarrior 我见过那些带有注入属性的例子。然而 simple-injector 不提供它们
  • 请向我们提供您遇到的异常的完整堆栈跟踪。
  • @LeandroSoares:你不能为 SimpleInjector 定义一个使用默认构造函数然后初始化这些属性的绑定吗?
  • @Steven stacktrace 添加了

标签: c# asp.net-mvc dependency-injection ioc-container simple-injector


【解决方案1】:

您必须使用像this 这样的注册依赖容器。这样,当 ASP.NET 将调用 SimpleInject 来解决依赖关系时,您可以指定所有接口以及匹配的实现。

你也可以像这样创建一个无参数的构造函数:

public CustomViewPage() : base(new ScriptFactory(), new Membership()...) { }

但我不建议这样做……最好的办法是让这个依赖解析逻辑正常工作。

【讨论】:

    猜你喜欢
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    相关资源
    最近更新 更多