简单注入器-自定义WebViewPage [英] Simple Injector - Custom WebViewPage

查看:100
本文介绍了简单注入器-自定义WebViewPage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用翻译的小应用程序(目前). 我的翻译服务称为翻译器(ITranslator).

I've a small application (for now) that uses translations. My translation Service is called Translator (ITranslator).

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

My problem is that I don't want to retrieve this class in every controller (which returns a view) so I may use it in my views.

我在使用ListService时遇到了类似的问题(我在其中存储了所有的SelectListItem列表).

I've a similar problem with a ListService (where I store all my SelectListItem lists).

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>

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

However, when running the application I've the following error:

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

'[NAMESPACE].CustomViewPage' does not contain a constructor that takes 0 arguments

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

But if I create a second constructor, Simple-Injector will throw an error since it doesn't support multiple constructors.

我如何才能实现自己想要的目标,或者不可能吗?

How may I achieve what I want, or isn't it possible?

修改

完整堆栈跟踪

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

c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\vs\520dfaa2\f5e4578c\App_Web_index.cshtml.a8d08dba.jtlk7fxz.0.cs(40): error CS1729: 'SportsHub.SDK.Infrastructure.CustomViewPage' does not contain a constructor that takes 0 arguments

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上似乎不起作用

As @StriplingWarrior and @Steven suggested, I used property injection, however it doesn't seem to be working on WebViewPage

我在服务上对其进行了测试,并且属性注入成功,但是在该类中,属性来自null.

I tested it on a service and Property Injection was successful, but in this class, the property comes null.

PS:我通过get; set;

PS: I made the properties public with get;set;

新的ViewPage:

New ViewPage:

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,我遵循以下文档.

推荐答案

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

You have to use a register dependency container like this. That's way, you can specify all the interfaces and what is the matching implementation when the ASP.NET will call that SimpleInject to resolve the dependency.

您还可以创建如下的无参数构造函数:

You can also create a parameterless constructor like this:

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

但是我不建议...最好的办法是使这种依赖关系解析逻辑起作用.

But I wouldn't recommend that... that best thing it's to have this dependency resolution logic working.

这篇关于简单注入器-自定义WebViewPage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆