在MVC4中为api和"常规"控制器使用Ninject DI

Soe*_*ren 4 ninject asp.net-mvc-4

可能重复:
MVC3 + Ninject - 如何?

在一个小型的mvc 4项目中,我正在尝试使用ninject实现依赖注入.

到目前为止,我已经使用api控制器了,但我对常规控制器没有任何好运.

我有一个NinjectResolver:

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
    {
        private readonly IKernel _kernel;

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

        public IDependencyScope BeginScope()
        {
            return new NinjectDependencyScope(_kernel.BeginBlock());
        }

        public override void Dispose()
        {
            _kernel.Dispose();
        }
    }
Run Code Online (Sandbox Code Playgroud)

还有一个NinjectScope:

public class NinjectDependencyScope : IDependencyScope
    {
        protected IResolutionRoot ResolutionRoot;

        public NinjectDependencyScope(IResolutionRoot kernel)
        {
            ResolutionRoot = kernel;
        }

        public object GetService(Type serviceType)
        {
            var request = ResolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
            return ResolutionRoot.Resolve(request).SingleOrDefault();
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            var request = ResolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
            return ResolutionRoot.Resolve(request).ToList();
        }

        public void Dispose()
        {
            var disposable = (IDisposable)ResolutionRoot;
            if (disposable != null) disposable.Dispose();
            ResolutionRoot = null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后我在我的Global.asax中设置它:

var kernel = new StandardKernel();
            kernel.Bind(typeof(IRepository)).To(typeof(Repository));

            GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
Run Code Online (Sandbox Code Playgroud)

然后我将一个存储库注入一个api控制器,如下所示:

private IRepository _repository;

public TestApiController(IRepository repository)
{
    _repository = repository;
}
Run Code Online (Sandbox Code Playgroud)

这样可以正常工作,但在常规控制器中执行相同操作会失败,并且"为此对象定义了无参数构造函数"错误.

有任何想法吗?

nem*_*esv 5

ASP.NET MVC使用IDependencyResolver与ASP.NET WebAPi 不同的名称Sytem.Web.Mvc.IDependencyResolver.

所以你需要一个NinjectDependencyResolverMVC控制器的新实现(幸运的是MVC和WepAPi IDependencyResolver几乎有相同的成员具有相同的签名,所以它很容易实现)

public class NinjectMvcDependencyResolver : NinjectDependencyScope, 
                                            System.Web.Mvc.IDependencyResolver
{
    private readonly IKernel _kernel;

    public NinjectDependencyResolver(IKernel kernel)
        : base(kernel)
    {
        _kernel = kernel;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以在以下内容中注册Global.asax:

DependencyResolver.SetResolver(new NinjectMvcDependencyResolver(kernel));
Run Code Online (Sandbox Code Playgroud)

  • 1.如果这是该类的整个实现,为什么要将`kernel`存储在一个字段中?你能不能让基类同时实现这两个接口? (3认同)