使用Asp.Net MVC和Web Api配置Ninject

Dot*_*mer 37 asp.net asp.net-mvc dependency-injection ninject repository-pattern

我已经设置了我的项目Ninject IoC.
我的项目有常规Asp.Net MVC控制器和Web Api控制器.现在,Ninject使用Web ApiNinject不适用于常规Asp.MVC控制器.
我的常规MVC控制器实现;

public class GalleryController : BaseController
{
    public GalleryController(IUow uow)
    {
        Uow = uow;
    }
    ........
}
Run Code Online (Sandbox Code Playgroud)

与常规控制器一起使用时出错

An error occurred when trying to create a controller of type 'Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.]
Run Code Online (Sandbox Code Playgroud)

但是,当我使用Web Api尝试相同的代码时,它可以工作

public class GalleryController : BaseApiController
{
    public GalleryController(IUow uow)
    {
        Uow = uow;
    }
    ......
}
Run Code Online (Sandbox Code Playgroud)

我的界面包含不同的存储库(工厂模式)

public interface IUow
{
    // Save pending changes to the data store.
    void Commit();

    //Repositoryries
    IRepository<Gallery> Gallery { get; }
    IMenuRepository Menus { get; }
}
Run Code Online (Sandbox Code Playgroud)

NinjectDependencyScope 类;

public class NinjectDependencyScope : IDependencyScope
{
    private IResolutionRoot resolver;

    internal NinjectDependencyScope(IResolutionRoot resolver)
    {
        Contract.Assert(resolver != null);

        this.resolver = resolver;
    }

    public void Dispose()
    {
        var disposable = resolver as IDisposable;
        if (disposable != null)
            disposable.Dispose();

        resolver = null;
    }

    public object GetService(Type serviceType)
    {
        if (resolver == null)
            throw new ObjectDisposedException("this", "This scope has already been disposed");

        return resolver.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        if (resolver == null)
            throw new ObjectDisposedException("this", "This scope has already been disposed");

        return resolver.GetAll(serviceType);
    }
}
Run Code Online (Sandbox Code Playgroud)

NinjectDependencyResolver 类;

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
    private IKernel kernel;

    public NinjectDependencyResolver(IKernel kernel)
        : base(kernel)
    {
        this.kernel = kernel;
    }

    public IDependencyScope BeginScope()
    {
        return new NinjectDependencyScope(kernel.BeginBlock());
    }
}
Run Code Online (Sandbox Code Playgroud)

Ninject Global.asax的配置;

public class IocConfig
{
    public static void RegisterIoc(HttpConfiguration config)
    {
        var kernel = new StandardKernel(); // Ninject IoC
        //kernel.Load(Assembly.GetExecutingAssembly()); //only required for asp.net mvc (not for webapi)
        // These registrations are "per instance request".
        // See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/

        kernel.Bind<RepositoryFactories>().To<RepositoryFactories>()
            .InSingletonScope();

        kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>();
        kernel.Bind<IUow>().To<Uow>();

        // Tell WebApi how to use our Ninject IoC
        config.DependencyResolver = new NinjectDependencyResolver(kernel);
    }
}
Run Code Online (Sandbox Code Playgroud)

Global.asax中

protected void Application_Start()
{

    // Tell WebApi to use our custom Ioc (Ninject)
    IocConfig.RegisterIoc(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    GlobalConfig.CustomizeConfig(GlobalConfiguration.Configuration);
    AreaRegistration.RegisterAllAreas();
}
Run Code Online (Sandbox Code Playgroud)

Ody*_*Ody 33

我已经写了一些要点来帮助配置Ninject与MVC和Web Api.只需包含文件:

要为具体类型添加Bindings,只需将它们放在Load()MainModule 的方法中即可.您可以根据需要创建任意数量的模块,以保持绑定的有序性.但是你还必须将它们添加到Modules属性中返回的数组中.

Then Add to the Application_Start() method

  • NinjectContainer.RegisterModules(NinjectModules.Modules) (for MVC)
  • NinjectHttpContainer.RegisterModules(NinjectHttpModules.Modules) (for WebApi)

Note that you can use the same NinjectModules.Modules for both the MVC and WebApi registration. I just separated it for clearity

UPDATE: Remember to Remove NinjectWebCommon.cs from your project as it loads and bootstraps a new kernel at Runtime which unfortunately is only for MVC.

UPDATE: You can also use

  • NinjectContainer.RegisterAssembly() (for MVC)
  • NinjectHttpContainer.RegisterAssembly() (for WebApi)

This will scan your current assembly for all modules. This way you can put your modules anywhere in your project and it will be registered


Dig*_*Dan 15

使用MVC 5和Web API 2.2,我通过确保包含以下NuGet包解决了这个问题:

  • Ninject.MVC5
  • Ninject.Web.WebApi.WebHost 用于Web API

这安装了其他Ninject依赖项并允许我RegisterServices通过NinjectWebCommon.cs.


Dot*_*mer 12

在搜索了很多之后,事实证明我们不能将Ninject与web api和常规mvc一起使用.我的意思是,我们必须单独配置存储库.

然后我找到了一篇很好的文章,解释了如何将Ninject与asp.net mvc和web api一起使用:http://www.codeproject.com/Articles/412383/Dependency-Injection-in-asp-net-mvc4-and-的WebAPI美

现在,我没有得到错误,它正在工作:D

更新1:

还尝试使用.NET Framework 4.5在MVC 4 Web API中编写依赖注入的简单实现


小智 6

这是一个适合我的简单解决方案:

  1. 在Visual Studio中,创建名为DemoApp的新Web应用程序项目,并确保已选择带有MVC和Web API引用的Empty模板: 在此输入图像描述
  2. 在包管理器控制台中逐个执行:

    安装包Ninject

    安装包Ninject.MVC5

  3. 将NinjectDependencyResolver.cs添加到IoC文件夹:

    using Ninject;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http.Dependencies;
    
    namespace DemoApp.IoC
    {
        public class NinjectDependencyResolver : IDependencyResolver, System.Web.Mvc.IDependencyResolver
        {
            private readonly IKernel kernel;
    
            public NinjectDependencyResolver(IKernel kernel)
            {
                this.kernel = kernel;
            }
    
            public IDependencyScope BeginScope()
            {
                return this;
            }
    
            public object GetService(Type serviceType)
            {
                return kernel.TryGet(serviceType);
            }
    
            public IEnumerable<object> GetServices(Type serviceType)
            {
                return kernel.GetAll(serviceType);
            }
    
            public void Dispose() { } //it is not necessary to implement any dispose logic here
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在App_Start/NinjectWebCommon.cs中进行以下更改:

    • 在CreateKernel方法中添加以下行:

      NinjectDependencyResolver ninjectResolver = new NinjectDependencyResolver(kernel); DependencyResolver.SetResolver(ninjectResolver); // MVC GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; // Web API

    • 在RegisterServices方法中添加绑定,如:

      kernel.Bind <IHelloService>().To <HelloService>();

现在NinjectWebCommon.cs看起来像:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(DemoApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(DemoApp.App_Start.NinjectWebCommon), "Stop")]

namespace DemoApp.App_Start
{
    using System;
    using System.Web;

    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;
    using Ninject.Web.Common;
    using DemoApp.IoC;
    using System.Web.Mvc;
    using System.Web.Http;
    using DemoApp.Config;

    public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

                RegisterServices(kernel);

                NinjectDependencyResolver ninjectResolver = new NinjectDependencyResolver(kernel);
                DependencyResolver.SetResolver(ninjectResolver); //MVC
                GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; //Web API

                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IHelloService>().To<HelloService>();
        }        
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 为了完整的示例,添加一些Mvc和Api控制器,以及IHelloService,HelloService的代码:

HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DemoApp.Config;
namespace DemoApp.Controllers
{
    public class HomeController : Controller
    {
        private IHelloService helloService;

        public HomeController(IHelloService helloService)
        {
            this.helloService = helloService;
        }

        // GET: /Home/
        public string Index()
        {
            return "home/index: " + helloService.GetMessage();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

UserController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using DemoApp.Config;
namespace DemoApp.Controllers
{
    public class UserController : ApiController
    {
        private IHelloService helloService;

        public UserController(IHelloService helloService)
        {
            this.helloService = helloService;
        }

        [HttpGet]
        public string Data()
        {
            return "api/user/data: " + helloService.GetMessage();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

IHelloService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DemoApp.Config
{
    public interface IHelloService
    {
       string GetMessage();
    }
}
Run Code Online (Sandbox Code Playgroud)

HelloService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DemoApp.Config
{
    public class HelloService : IHelloService
    {
        public string GetMessage()
        {
            return "Hi";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 最终结构应如下所示: 在此输入图像描述

    现在在浏览器中进行一些测试.对我来说是:

    HTTP://本地主机:51156 /首页/指数

    HTTP://本地主机:51156/API /用户/数据

就是这样.


归档时间:

查看次数:

47265 次

最近记录:

6 年,1 月 前