如何在WebApi OwinHost Startup中使用Ninject引导程序?

时间:2014-05-27 18:47:50

标签: c# asp.net-web-api ninject owin bootstrapper

我正在从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内核直到启动后才会创建。但是,在Cors和OAuth中间件注册的启动注册过程中,我需要Ninject DI。在迁移到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.Initialize第二次,结果不好。

在Startup中创建和使用ninject内核并仍然注册Ninject / WebAPI中间件的正确方法是什么?

3 个答案:

答案 0 :(得分:21)

将以下nuget-packages添加到您的应用程序中:

  1. 安装包Microsoft.AspNet.WebApi.Owin
  2. 安装包Ninject
  3. 如果您使用的是web api 5.0.0.0版,则还需要下载Ninject Resolver class from the repo以避免兼容性问题。

    创建一个返回内核对象的静态方法

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

答案 1 :(得分:5)

手动创建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); } ,而不是创建另一个。

/*
     _ _      _       _
 ___| (_) ___| | __  (_)___
/ __| | |/ __| |/ /  | / __|
\__ \ | | (__|   < _ | \__ \
|___/_|_|\___|_|\_(_)/ |___/

 */
/* global window, document, define, jQuery, setInterval, clearInterval */
(function(factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        define(['jquery'], factory);
    } else if (typeof exports !== 'undefined') {
        module.exports = factory(require('jquery'));
    } else {
        factory(jQuery);
    }

}(function($) {
    'use strict';
    var Slick = window.Slick || {};

    Slick = (function() {

        var instanceUid = 0;

        function Slick(element, settings) {

            var _ = this, dataSettings;

            _.defaults = {
                accessibility: true,
                adaptiveHeight: false,
                appendArrows: $(element),
                appendDots: $(element),
                arrows: true,
                asNavFor: null,
                prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button">Previous</button>',
                nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button">Next</button>',
                autoplay: false,
                autoplaySpeed: 3000,
                centerMode: false,
                centerPadding: '50px',
                cssEase: 'ease',
                customPaging: function(slider, i) {
                    return '<button type="button" data-role="none" role="button" aria-required="false" tabindex="0">' + (i + 1) + '</button>';
                },
                dots: false,
                dotsClass: 'slick-dots',
                draggable: true,
                easing: 'linear',
                edgeFriction: 0.35,
                fade: false,
                focusOnSelect: false,
                infinite: true,
                initialSlide: 0,
                lazyLoad: 'ondemand',
                mobileFirst: false,
                pauseOnHover: true,
                pauseOnDotsHover: false,
                respondTo: 'window',
                responsive: null,
                rows: 1,
                rtl: false,
                slide: '',
                slidesPerRow: 1,
                slidesToShow: 1,
                slidesToScroll: 1,
                speed: 500,
                swipe: true,
                swipeToSlide: false,
                touchMove: true,
                touchThreshold: 5,
                useCSS: true,
                variableWidth: false,
                vertical: false,
                verticalSwiping: false,
                waitForAnimate: true,
                zIndex: 1000
            };

            _.initials = {
                animating: false,
                dragging: false,
                autoPlayTimer: null,
                currentDirection: 0,
                currentLeft: null,
                currentSlide: 0,
                direction: 1,
                $dots: null,
                listWidth: null,
                listHeight: null,
                loadIndex: 0,
                $nextArrow: null,
                $prevArrow: null,
                slideCount: null,
                slideWidth: null,
                $slideTrack: null,
                $slides: null,
                sliding: false,
                slideOffset: 0,
                swipeLeft: null,
                $list: null,
                touchObject: {},
                transformsEnabled: false,
                unslicked: false
            };

            $.extend(_, _.initials);

            _.activeBreakpoint = null;
            _.animType = null;
            _.animProp = null;
            _.breakpoints = [];
            _.breakpointSettings = [];
            _.cssTransitions = false;
            _.hidden = 'hidden';
            _.paused = false;
            _.positionProp = null;
            _.respondTo = null;
            _.rowCount = 1;
            _.shouldClick = true;
            _.$slider = $(element);
            _.$slidesCache = null;
            _.transformType = null;
            _.transitionType = null;
            _.visibilityChange = 'visibilitychange';
            _.windowWidth = 0;
            _.windowTimer = null;

            dataSettings = $(element).data('slick') || {};

            _.options = $.extend({}, _.defaults, dataSettings, settings);

            _.currentSlide = _.options.initialSlide;

            _.originalSettings = _.options;

            if (typeof document.mozHidden !== 'undefined') {
                _.hidden = 'mozHidden';
                _.visibilityChange = 'mozvisibilitychange';
            } else if (typeof document.webkitHidden !== 'undefined') {
                _.hidden = 'webkitHidden';
                _.visibilityChange = 'webkitvisibilitychange';
            }

          

答案 2 :(得分:1)

除了Olif的帖子:

  1. install-package ninject.extensions.conventions

  2. 在您的启动类中添加:using Ninject.Extensions.Conventions;

  3. 而不是手动绑定:

  4.  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();
                    });
    

    这将查看您的程序集,并自动执行绑定。