2

У меня есть небольшое приложение (на данный момент), которое использует переводы. Услуга перевода называется Translator (ITranslator).Простой инжектор - Пользовательский WebViewPage

Моя проблема в том, что я не хочу извлекать этот класс в каждом контроллере (который возвращает представление), поэтому я могу использовать его в своих представлениях.

У меня аналогичная проблема с 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' does not contain a constructor that takes 0 arguments

Но если я создаю второй конструктор, Simple-Injector вызовет ошибку sinc e он не поддерживает несколько конструкторов.

Как я могу достичь того, чего хочу, или это невозможно?

Редактировать

Полных трассировки стека

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

Как @StriplingWarrior и @Steven предложили, я использовал инъекцию собственности, однако не похоже, работают на WebViewPage

Я протестировал его на службе, и свойство Injection было успешным, но в этом классе собственность прибывает null.

PS: Я создал свойства public с get; set;

Новый 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 я следовал следующий documents.

+0

Это может быть актуально: http://stackoverflow.com/questions/7656195/can-you-inject-dependencies-into-a-constructor-of-a-custom-webviewpage-using-an – StriplingWarrior

+0

@StriplingWarrior I ' мы видели эти примеры с атрибутами впрыска.Однако простой инжектор не предоставляет их –

+0

Просьба предоставить нам полную трассировку стека за исключением, которое вы получаете. – Steven

ответ

0

Вы должны использовать контейнер зависимостей регистра, например this. Таким образом, вы можете указать все интерфейсы и то, что соответствует реализации, когда ASP.NET вызовет этот SimpleInject для разрешения зависимости.

Вы также можете создать конструктор без параметров, как это:

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

Но я бы не рекомендовал, что ... что самое лучшее это иметь это разрешение логики зависимость работает.