2017-02-21 5 views
2

Ich benutze Ninject 3 in einer MVC5-basierten Website, und versuchen zu erarbeiten, wie DI mit einem Typ arbeiten, der Eigenschaften eines Uri.Host Wert überprüft sein Konstruktor. Ich möchte, dass die Bindung irgendwie die aktuelle URL angibt. Die minimale Struktur Ich habe versucht, zunächst ist:Ninject Bindung für einen Typ, der die aktuelle erfordert Request.Url

public class StructuredUrlTester : IStructuredUrlTester 
{ 
    // Expose public getters for parts of the uri.Host value 
    bool MyBooleanProperty { get; private set; } 

    public StructuredUrlTester(Uri uri) 
    { 
     // Test the value of uri.Host and extract parts via regex 
    } 
} 

// In Global.asax.cs 
public class MvcApplication : NinjectHttpApplication 
{ 
    protected override IKernel CreateKernel() 
    { 
     kernel.Bind<IStructuredUrlTester>() 
      .To<StructuredUrlTester>() 
      .InTransientScope(); 
      .WithConstructorArgument("uri", Request.Url); 
    } 
} 

// In MyController.cs 
public class MyController : Controller 
{ 
    private readonly IStructuredUrlTester _tester; 

    public ContentPageController(IStructuredUrlTester tester) 
    { 
     this._tester = tester; 
    } 

    public ActionResult Index() 
    { 
     string viewName = "DefaultView"; 
     if (this._tester.MyBooleanProperty) 
     { 
      viewName = "CustomView"; 
     } 

     return View(viewName); 
    } 
} 

Wie der CreateKernel() Aufruf geschieht, bevor das Request Objekt verfügbar ist, der .WithConstructorArgument() Teil eine Ausnahme auslöst ("System.Web.HttpException: Anfrage in diesem Zusammenhang nicht verfügbar ist ").

Wie kann ich die Bindung der Schnittstelle zum konkreten Typ bereitstellen, während ich auch die z. HttpContext.Current.Request.Url Wert (innerhalb des Controllers verfügbar) für den Konstruktor des konkreten Typs zur Laufzeit, wenn dieser verfügbar ist?

+0

wickeln Sie den httpcontext in eine Abstraktion. – Nkosi

+0

Haben Sie erwogen, von hier aus URI zu holen? System.Web.HttpContext.Current.Request.Url im Konstruktor von StructuredUrlTester – Dimitri

+0

Gibt es einen klaren Grund, warum Sie diese Logik hinter und Abstraktion implementieren müssen? Klar würde ich es einfach auf eine Helfer/Extension-Methode setzen ... – kayess

Antwort

2

die gewünschte Funktionalität in einer Abstraktion Wrap:

public interface IUriProvider { 
    Uri Current { get; } 
} 

Umgestalten der Tester Klasse:

public class StructuredUrlTester : IStructuredUrlTester { 
    // Expose public getters for parts of the uri.Host value 
    bool MyBooleanProperty { get; private set; } 

    public StructuredUrlTester(IUriProvider provider) { 
     Uri uri = provider.Current; 
     // Test the value of uri.Host and extract parts via regex 
    } 
} 

Die Provider-Implementierung die Request.Url wickeln sollte:

public class UriProvider : IUriProvider { 
    public Uri Current { get { return HttpContext.Current.Request.Url; } } 
} 

Und beachten Sie, dass die Current Eigentum sollte eigentlich Witz genannt werden Hin der Aktion eines Controllers, wo HttpContext und ihre Anfrage verfügbar sind.

+0

Absolut super, funktionierte genau so, wie ich es brauchte. Ich kann jetzt sehen, wie die Verwendung des Providers bedeutet, dass auf den 'HttpContext' nicht zugegriffen wird, bis' MyController' konstruiert wird (was durch Ninject auch den 'StructuredUrlTester' bedeutet), zu welchem ​​Zeitpunkt das Request-Objekt gefüllt wurde und ist verfügbar. Danke für Ihre Hilfe! –

Verwandte Themen