2017-02-21 1 views
2

J'utilise Ninject 3 dans un site Web basé sur MVC5, et essaye de trouver comment faire fonctionner DI avec un type qui teste les propriétés d'une valeur Uri.Host passée dans son constructeur. J'aimerais que la liaison fournisse l'URL actuelle. La structure minimale que j'ai essayé est d'abord:Reliure Ninject pour un type qui requiert l'actuel 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); 
    } 
} 

Comme le CreateKernel() appel se produit avant que l'objet Request est disponible, la partie .WithConstructorArgument() jette une exception ("System.Web.HttpException: demande n'est pas disponible dans ce contexte ").

Comment puis-je fournir la liaison de l'interface à un type de béton, tout en étant également capable de fournir par ex. HttpContext.Current.Request.Url valeur (disponible dans le Controller) au constructeur du type concret, au moment de l'exécution quand il est disponible?

+0

envelopper le httpcontext dans une abstraction. – Nkosi

+0

Avez-vous envisagé d'obtenir uri à partir de maintenant System.Web.HttpContext.Current.Request.Url, dans le constructeur de StructuredUrlTester – Dimitri

+0

Y a-t-il une raison claire pour laquelle vous devez implémenter cette logique derrière et abstraction? Simplement je le mettrais juste à une méthode d'aide/extension ... – kayess

Répondre

2

Enveloppez la fonctionnalité souhaitée dans une abstraction:

public interface IUriProvider { 
    Uri Current { get; } 
} 

Refactor la classe testeur:

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

La mise en œuvre du fournisseur doit envelopper le Request.Url:

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

Et notez que le Propriété Current devrait être effectivement appelé esprit hin l'action d'un contrôleur où HttpContext et sa demande sont disponibles.

+0

Absolument génial, a travaillé comme j'avais besoin. Je peux voir maintenant comment utiliser le fournisseur signifie que le 'HttpContext' n'est pas accédé jusqu'à ce que MyController soit construit (qui par Ninject signifie que le' StructuredUrlTester' est également construit), à quel moment l'objet Request a été rempli et est disponible. Merci de votre aide! –