如何使用 OWIN 将 Ninject Controller Factory 添加到 ASP.NET MVC 应用程序?
How do I add Ninject Controller Factory to an ASP.NET MVC app with OWIN?
我正在使用 Visual Studio 2012 Premium、.NET Framework 4.5.1 和 C# 开发 ASP.NET Web Api 2.2 项目。
我创建了一个空的 ASP.NET MVC 5
项目。我删除了 Global.asax
并创建了这个 Startup.cs
class:
using Microsoft.Owin;
using Ninject;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
using System.Reflection;
using System.Web.Http;
using System.Web.Routing;
using MyProject.Web.API.App_Start;
[assembly: OwinStartup(typeof(MyProject.Web.API.Startup))]
namespace MyProject.Web.API
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
var webApiConfiguration = new HttpConfiguration();
webApiConfiguration.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
webApiConfiguration.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
webApiConfiguration.Routes.MapHttpRoute(
name: "ProductionOrderActionApi",
routeTemplate: "api/MyProductionOrders/{orderNumber}/{action}",
defaults: new { controller = "MyProductionOrders" });
app.UseNinjectMiddleware(CreateKernel);
app.UseNinjectWebApi(webApiConfiguration);
}
private static StandardKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
var containerConfigurator = new NinjectConfigurator();
containerConfigurator.Configure(kernel);
}
}
}
该项目在 ApiController classes, but when I try to access to a Controller 下工作正常我收到以下错误:No Parameterless constructor defined for this object.
。
这是我的 Controller
:
public class MyController : Controller
{
private readonly IExceptionLogHelper m_ExceptionLoggerHelper;
private readonly IGenericRepository<MyModel> _myRepo;
public MyController(
IExceptionLogHelper exceptionLoggerHelper,
IGenericRepository<MyModel> myModelRepo)
{
_exceptionLoggerHelper = exceptionLoggerHelper;
_myRepo = myModelRepo;
}
//
// GET: /UploadChinaCodes/
public ActionResult Index()
{
return View();
}
}
和NinjectConfigurator
class:
public class NinjectConfigurator
{
public void Configure(IKernel container)
{
AddBindings(container);
}
private void AddBindings(IKernel container)
{
// Exception logger.
container.Bind<IExceptionLogHelper>().To<ExceptionLogHelper>();
// Repositories.
container.Bind<IGenericRepository<MyModel>>().To<GenericRepository<MyModel>>();
}
}
这些是已安装的 NuGet 包:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.1.2" targetFramework="net45" />
<package id="log4net" version="2.0.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net451" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client.es" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core.es" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost.es" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net451" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net451" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
<package id="Ninject" version="3.2.2.0" targetFramework="net45" />
<package id="Ninject.Extensions.ContextPreservation" version="3.2.0.0" targetFramework="net45" />
<package id="Ninject.Extensions.NamedScope" version="3.2.0.0" targetFramework="net45" />
<package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net45" />
<package id="Ninject.Web.Common.OwinHost" version="3.2.3.0" targetFramework="net45" />
<package id="Ninject.Web.WebApi" version="3.2.4.0" targetFramework="net45" />
<package id="Ninject.Web.WebApi.OwinHost" version="3.2.4.0" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>
顺便说一下,我正在使用 Owin
。
我该如何解决这个问题?
您必须为 ninject 创建自定义 DefaultControllerFactory
:
using Ninject;
using System;
using System.Web.Mvc;
namespace MyProject.Web.API.Factories
{
public class NinjectControllerFactory : DefaultControllerFactory
{
public IKernel Kernel { get; private set; }
public NinjectControllerFactory(IKernel kernel)
{
this.Kernel = kernel;
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
IController controller = null;
if (controllerType != null)
controller = (IController)Kernel.Get(controllerType);
return controller;
}
}
}
并在 Startup
上注册 class:
using Microsoft.Owin;
using Ninject;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
using System.Reflection;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using MyProject.Web.API.Factories;
[assembly: OwinStartup(typeof(MyProject.Web.API.Startup))]
namespace MyProject.Web.API
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
var webApiConfiguration = new HttpConfiguration();
webApiConfiguration.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
webApiConfiguration.Routes.MapHttpRoute(
name: "ProductionOrderActionApi",
routeTemplate: "api/ProductionOrders/{orderNumber}/{action}",
defaults: new { controller = "ProductionOrders" });
app.UseNinjectMiddleware(CreateKernel);
app.UseNinjectWebApi(webApiConfiguration);
}
private static StandardKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(kernel));
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
var containerConfigurator = new NinjectConfigurator();
containerConfigurator.Configure(kernel);
}
}
}
我在 CreateKernel
方法中添加了这一行 ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(kernel));
。
我正在使用 Visual Studio 2012 Premium、.NET Framework 4.5.1 和 C# 开发 ASP.NET Web Api 2.2 项目。
我创建了一个空的 ASP.NET MVC 5
项目。我删除了 Global.asax
并创建了这个 Startup.cs
class:
using Microsoft.Owin;
using Ninject;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
using System.Reflection;
using System.Web.Http;
using System.Web.Routing;
using MyProject.Web.API.App_Start;
[assembly: OwinStartup(typeof(MyProject.Web.API.Startup))]
namespace MyProject.Web.API
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
var webApiConfiguration = new HttpConfiguration();
webApiConfiguration.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
webApiConfiguration.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
webApiConfiguration.Routes.MapHttpRoute(
name: "ProductionOrderActionApi",
routeTemplate: "api/MyProductionOrders/{orderNumber}/{action}",
defaults: new { controller = "MyProductionOrders" });
app.UseNinjectMiddleware(CreateKernel);
app.UseNinjectWebApi(webApiConfiguration);
}
private static StandardKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
var containerConfigurator = new NinjectConfigurator();
containerConfigurator.Configure(kernel);
}
}
}
该项目在 ApiController classes, but when I try to access to a Controller 下工作正常我收到以下错误:No Parameterless constructor defined for this object.
。
这是我的 Controller
:
public class MyController : Controller
{
private readonly IExceptionLogHelper m_ExceptionLoggerHelper;
private readonly IGenericRepository<MyModel> _myRepo;
public MyController(
IExceptionLogHelper exceptionLoggerHelper,
IGenericRepository<MyModel> myModelRepo)
{
_exceptionLoggerHelper = exceptionLoggerHelper;
_myRepo = myModelRepo;
}
//
// GET: /UploadChinaCodes/
public ActionResult Index()
{
return View();
}
}
和NinjectConfigurator
class:
public class NinjectConfigurator
{
public void Configure(IKernel container)
{
AddBindings(container);
}
private void AddBindings(IKernel container)
{
// Exception logger.
container.Bind<IExceptionLogHelper>().To<ExceptionLogHelper>();
// Repositories.
container.Bind<IGenericRepository<MyModel>>().To<GenericRepository<MyModel>>();
}
}
这些是已安装的 NuGet 包:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.1.2" targetFramework="net45" />
<package id="log4net" version="2.0.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net451" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client.es" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core.es" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost.es" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net451" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net451" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
<package id="Ninject" version="3.2.2.0" targetFramework="net45" />
<package id="Ninject.Extensions.ContextPreservation" version="3.2.0.0" targetFramework="net45" />
<package id="Ninject.Extensions.NamedScope" version="3.2.0.0" targetFramework="net45" />
<package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net45" />
<package id="Ninject.Web.Common.OwinHost" version="3.2.3.0" targetFramework="net45" />
<package id="Ninject.Web.WebApi" version="3.2.4.0" targetFramework="net45" />
<package id="Ninject.Web.WebApi.OwinHost" version="3.2.4.0" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>
顺便说一下,我正在使用 Owin
。
我该如何解决这个问题?
您必须为 ninject 创建自定义 DefaultControllerFactory
:
using Ninject;
using System;
using System.Web.Mvc;
namespace MyProject.Web.API.Factories
{
public class NinjectControllerFactory : DefaultControllerFactory
{
public IKernel Kernel { get; private set; }
public NinjectControllerFactory(IKernel kernel)
{
this.Kernel = kernel;
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
IController controller = null;
if (controllerType != null)
controller = (IController)Kernel.Get(controllerType);
return controller;
}
}
}
并在 Startup
上注册 class:
using Microsoft.Owin;
using Ninject;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
using System.Reflection;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using MyProject.Web.API.Factories;
[assembly: OwinStartup(typeof(MyProject.Web.API.Startup))]
namespace MyProject.Web.API
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
var webApiConfiguration = new HttpConfiguration();
webApiConfiguration.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
webApiConfiguration.Routes.MapHttpRoute(
name: "ProductionOrderActionApi",
routeTemplate: "api/ProductionOrders/{orderNumber}/{action}",
defaults: new { controller = "ProductionOrders" });
app.UseNinjectMiddleware(CreateKernel);
app.UseNinjectWebApi(webApiConfiguration);
}
private static StandardKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(kernel));
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
var containerConfigurator = new NinjectConfigurator();
containerConfigurator.Configure(kernel);
}
}
}
我在 CreateKernel
方法中添加了这一行 ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(kernel));
。