Ninject: Как не использовать Ninject в файле "ashx" и все же не получить исключение? - PullRequest
2 голосов
/ 06 марта 2012

Это то, что я использую для внедрения зависимостей в моем проекте MVC3,

public class NinjectControllerFactory : DefaultControllerFactory
{
    private readonly IKernel _ninjectKernel;
    public NinjectControllerFactory()
    {
        _ninjectKernel = new StandardKernel();
        AddBindings();
    }
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return controllerType == null ? null : (IController)_ninjectKernel.Get(controllerType);
    }

    private void AddBindings()
    {
        _ninjectKernel.Bind<IUserRepository>().To<UserRepository>().InSingletonScope();            
    }
}

но у меня огромная проблема: я хочу использовать универсальный обработчик ".ashx" для реализации моей логики.

Но я получаю исключение, потому что httphandler не является контроллером.

вот исключение:

    Server Error in '/' Application.
The IControllerFactory 'Infrastructure.NinjectFactory.NinjectControllerFactory' did not return a controller for the name 'registercustomer.ashx'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: The IControllerFactory 'Infrastructure.NinjectFactory.NinjectControllerFactory' did not return a controller for the name 'registercustomer.ashx'.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[InvalidOperationException: The IControllerFactory 'Infrastructure.NinjectFactory.NinjectControllerFactory' did not return a controller for the name 'registercustomer.ashx'.]
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +422803
   System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
   System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8971636
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.547 

Теперь вопрос: как мне реализовать работу с этой ошибкой, чтобы я мог использовать HttpHandler и при этом продолжать использовать Ninject в моем проекте?

Заранее спасибо.

1 Ответ

1 голос
/ 06 марта 2012

Из-за того, что HttpHandler был создан фреймворком, и нет перехвата или фабричного метода для перехвата создания файла ashx, ninject не может создать этот объект.

Однако вы можете использовать вызовы службы поиска или инъекцию свойств из ashx, чтобы запросить зависимости из кода ashx.Но, насколько мне известно, у ashx должен быть конструктор по умолчанию, и тогда вы можете либо разрешить зависимости изнутри конструктора (или где угодно) с помощью локатора службы (менее предпочтительный метод) или с помощью внедрения свойства просто так:

public class Handler
{
    [Inject]
    public IService Service { get; set; }
}

EDIT: также, чтобы указать mvc не обрабатывать файл ashx, вам нужно добавить это, чтобы игнорировать маршрут:

routes.IgnoreRoute("{resource}.ashx/{*pathInfo}");
...