Simple Injector - Custom WebViewPage

天大地大妈咪最大 提交于 2019-12-11 00:40:06

问题


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.

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

and the usage:

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

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

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

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?

Edit

Full stack trace

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)

Edit 2

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

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

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

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 + "\">");
    }

For the InjectAttribute I've followed the following documents.


回答1:


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.



来源:https://stackoverflow.com/questions/38704650/simple-injector-custom-webviewpage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!