ASP.NET MVC und Dependency Injection für Views – Part 3


Einen View mit Dependency Injection (Di) zu initialisieren ist möglich, sollte aber nicht prinzipiell verwendet werden, sondern nur wenn z.B. ein Lokalisierungsservice direkt Strings auf dem View ausgeben und übersetzten soll. Denn im View soll normalerweise keine Logik untergebracht werden, sondern nur zur reinen Anzeige der Modeldaten dienen.

Um einen View mit Hilfe von Di zu initialisieren sind die folgenden Schritte notwendig.

Überschreiben der Standardklasse für die ViewCreation “WebViewPage”, dafür müssen wir unsere eigene Klasse anlegen die von “WebViewPage” ableitet.

 public abstract class CustomDiWebViewPage<TModel> : WebViewPage<TModel>
    {
        /// <summary>
        /// Lokalisation Interface, welches per Property Injektion vom DiFramework initialisiert wird.
        /// </summary>
        public ILocalizeable Localizeable { get; set; }
    }

Achtung wichtig ist hier das “abstract”. Das Interface und die passende Implementierung stellen wir zur Verfügung und könnte z.B. folgendermaßen aussehen:

 public interface ILocalizeable
 {
        /// <summary>
        /// den passend Lokalisierten String zurückgeben
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        string GetLocalizedString(string name);
 }

 /// <summary>
 /// Interface und Implementierung nur zu Demonstrationszwecken im gleichen Projekt!
 /// </summary>
 public class Localizeable : ILocalizeable
 {
     /// <summary>
     /// den passend Lokalisierten String zurückgeben
     /// </summary>
    public string GetLocalizedString(string name)
     {
         //TODO Lokalisierung entsprechend einbinden.
        return name + " localized";
     }
 }

Damit MVC auch weiß welche Klasse für das “anzeigen” des Views zuständig ist, gibt es hier zwei Möglichkeiten:

1. In der web.config, die sich im Views Verzeichnis befindet die Zeile mit “WebViewPage” durch unsere Benutzerdefinierte ViewPage ersetzen.

 <!--<pages pageBaseType="System.Web.Mvc.WebViewPage">-->
 <pages pageBaseType="User.Web.UI.Helper.CastleWindsor.CustomDiWebViewPage">
   <namespaces>
     <add namespace="System.Web.Mvc" />
     <add namespace="System.Web.Mvc.Ajax" />
     <add namespace="System.Web.Mvc.Html" />
     <add namespace="System.Web.Optimization"/>
     <add namespace="System.Web.Routing" />
     <add namespace="User.Web.UI" />
     <add namespace="User.Global.Resources" />
     <add namespace="User.Web.Common.WebAttributes" />
   </namespaces>
 </pages>

Jetzt wird bei jedem Rendern einer Seite unsere “CustomDiWebViewPage” verwendet.

2. Im View selbst nicht @model verwenden sondern über @inherits den View angeben über den die Seite gerendert werden soll z.B.:

@inherits User.Web.UI.Helper.CastleWindsor.CustomDiWebViewPage<User.Web.Models.Account.LoginModel>

 

Im View selbst kann dann einfach auf die Lokalisierung zugegriffen werden

@Localizeable.GetLocalizedString(„Test Lokalisierung“)

So jetzt zum wichtigsten Schritt, die Dependency Injection. Leider ist es mit Castle Windsor und einer CustomControllerFactory (älterer Post von mir über Di und Castle Windsor) nicht möglich einen View wie oben beschrieben zu Injecten.

Out of the Box wird das ganze aber z.B. von ninject unterstützt und mit Hilfe des NuGet Packages:

https://www.nuget.org/packages/Ninject.MVC3

muss für die Dependency Injection für einen View nur noch unsere Implementierung dem Interface zugewiesen werden im ninject DiKernel und alles weitere Funktioniert durch die Implementierung von IDependencyResolver von ninject. Wenn ich noch ermitteln kann, wie das ganze auch mit Castle Windsor funktioniert, werde ich den Post entsprechend anpassen.

Quellen:

http://bradwilson.typepad.com/blog/2010/07/service-location-pt3-views.html

http://sachabarbs.wordpress.com/2011/02/05/mvc-dependency-injection-into-views/

http://weblogs.asp.net/scottgu/archive/2010/10/19/asp-net-mvc-3-new-model-directive-support-in-razor.aspx

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s