Как использовать загрузчик Ninject в WebApi OwinHost Startup?
Я переношу из IIS WebAPI в OwinHost. Используя последние версии пакетов nuget, выпущенные до выпуска, я успешно использовал здесь следующие инструкции:
https://github.com/ninject/Ninject.Web.Common/wiki/Setting-up-a-OWIN-WebApi-application
Вот мой код:
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
app.UseNinjectMiddleware(CreateKernel);
app.UseNinjectWebApi(config);
}
private static StandardKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
...
}
Но в моем коде и примере документации ядро Ninject создается не после запуска. Мне нужен Ninject DI, однако, в процессе регистрации Startup для регистрации промежуточного программного обеспечения Cors и OAuth. Прежде чем перейти на OwinHost, я мог бы сделать что-то вроде этого:
public void Configuration(IAppBuilder app)
{
_bootstrapper = new Bootstrapper();
_bootstrapper.Initialize(CreateKernel);
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
// USE _boostrapper.Kernel here
app.UseNinjectMiddleware(CreateKernel);
app.UseNinjectWebApi(config);
}
Но внутренне, OwinBootstrapper.Execute в конечном итоге вызовет CreateKernel и bootstrapper. Внедрение во второй раз с плохими последствиями.
Каков правильный способ создания и использования ядра ninject в составе Startup и по-прежнему регистрировать промежуточное программное обеспечение Ninject/WebAPI?
Ответы
Ответ 1
Добавьте в приложение следующие пакеты nuget:
- Установочный пакет Microsoft.AspNet.WebApi.Owin
- Установить пакет Ninject
Если вы используете веб-api версии 5.0.0.0, вам также необходимо загрузить класс Ninject Resolver из репо, чтобы избежать проблем с совместимостью.
Создайте статический метод, возвращающий объект Kernel
public static class NinjectConfig
{
public static IKernel CreateKernel()
{
var kernel = new StandardKernel();
//Create the bindings
kernel.Bind<IProductsRepository>().To<ProductRepository>();
return kernel;
}
}
Затем вы можете использовать ninject в своем классе запуска
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.DependencyResolver = new NinjectResolver(NinjectConfig.CreateKernel());
config.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id=RouteParameter.Optional });
app.UseWebApi(config);
}
}
Ответ 2
Создайте kernel
вручную, а затем создайте UseNinjectMiddleware
, используя один и тот же, вместо создания другого.
public void Configuration(IAppBuilder app)
{
var kernel = CreateKernel()
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
// USE kernel here
app.UseNinjectMiddleware(() => kernel);
app.UseNinjectWebApi(config);
}
Ответ 3
В дополнение к сообщению Olif:
public static IKernel CreateKernel()
{
var kernel = new StandardKernel();
//Create the bindings
kernel.Bind<IProductsRepository>().To ProductRepository ();
return kernel;
}
Теперь вы можете сделать:
kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.BindDefaultInterface();
});
Это будет выглядеть через вашу сборку и автоматически выполнять привязку.