2017-02-21 63 views
2

Я использую Ninject 3 на веб-сайте MVC5 и пытаюсь выяснить, как заставить DI работать с типом, который проверяет свойства значения Uri.Host, переданного в его конструктор. Я бы хотел, чтобы привязка каким-то образом предоставляла текущий URL-адрес. Минимальная структура Я пытался изначально:Ninject привязка для типа, который требует текущего 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); 
    } 
} 

Как CreateKernel() вызова происходит до того, как Request объекта доступен, .WithConstructorArgument() части бросает исключение ("System.Web.HttpException: Запрос не доступен в этом контексте «).

Как я могу обеспечить привязку интерфейса к конкретному типу, в то же время будучи в состоянии предоставить, например, HttpContext.Current.Request.Url (доступно в контроллере) для конструктора конкретного типа во время выполнения, когда он доступен?

+0

заверните httpcontext в абстракции. – Nkosi

+0

Вы рассматривали получение uri здесь System.Web.HttpContext.Current.Request.Url, внутри конструктора StructuredUrlTester – Dimitri

+0

Есть ли ясная причина, почему вам нужно реализовать эту логику и абстракцию? Я просто хотел бы передать его методу помощника/расширения ... – kayess

ответ

2

Wrap требуемой функциональности в абстракции:

public interface IUriProvider { 
    Uri Current { get; } 
} 

рефакторинга класс тестер:

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

Реализация провайдер должен обмотать Request.Url:

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

И заметим, что Current собственность должна называться остроумием hin действие контроллера, где HttpContext и его запрос доступны.

+0

Абсолютно отлично, работал так, как мне было нужно. Теперь я вижу, как использование провайдера означает, что «HttpContext» недоступен до тех пор, пока не будет создан «MyController» (который через Ninject означает, что «StructuredUrlTester» также создается), когда объект запроса был заполнен и доступен. Спасибо за помощь! –