无法使用Ninject将依赖项注入到从Angular Service调用的ASP.NET Web API控制器中

MTL*_*323 3 c# asp.net-mvc entity-framework ninject.web.mvc angularjs

我正在使用Ninject和ASP.NET MVC 4.我正在使用存储库并希望进行构造函数注入以将存储库传递给其中一个控制器.

这是我的上下文对象(EntityFramework),它实现了我的StatTracker接口:

public class StatTrackerRepository : IStatTrackerRepository
{
    private GolfStatTrackerEntities _ctx;

    public StatTrackerRepository(GolfStatTrackerEntities ctx)
    {
        _ctx = ctx;
    }

    public IQueryable<Facility> GetFacilites()
    {
        return _ctx.Facilities;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的Repository接口:

public interface IStatTrackerRepository
{ 
    IQueryable<Facility> GetFacilites();
}
Run Code Online (Sandbox Code Playgroud)

然后调用我的家庭控制器:

public class HomeController : Controller
{
    public IStatTrackerRepository _repo { get; set; }

    public HomeController(IStatTrackerRepository repo)
    {
        _repo = repo;
    }

    public ActionResult Index()
    {
        var facilities = _repo.GetFacilites().ToList();
        return View(facilities);
    }
}
Run Code Online (Sandbox Code Playgroud)

页面加载正确,但是,一旦页面加载,它立即使用angularjs控制器调用$ http方法:

function facilityIndexController($scope, $http) {
    $scope.data = [];
    $http({ method: 'GET', url: '/api/facility' }).
        success(function(result) {
            angular.copy(result.data, $scope.data);
        }).error(function() {
            alert("Could not load facilities");
        });
}
Run Code Online (Sandbox Code Playgroud)

...调用以下API控制器:

public class FacilityController : ApiController
{
    public IStatTrackerRepository _repo { get; set; }
    public GolfStatTrackerEntities ctx { get; set; }

    //public FacilityController()
    //{
    //    _repo = new StatTrackerRepository(ctx);
    //}

    public FacilityController(IStatTrackerRepository repo)
    {
        _repo = repo;
    }

    public IEnumerable<Facility> Get()
    {
        var facilities = _repo.GetFacilites().ToList();
        return facilities;
    }
}
Run Code Online (Sandbox Code Playgroud)

....它落入角度$ http调用的错误函数,因为从未运行FacilityController(IStatTrackerRepository repo).

我已经尝试使用无参数的contstructor来为FacilityController()实例化一个StatTrackerRepository(ctx),但是,当我这样做时,我得到一个NullReferenceException.

我的Ninject配置如下:

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);
        //GlobalConfiguration.Configuration.DependencyResolver =
        //    new NinjectResolver(kernel);
        return kernel;
    }
    catch
    {
        kernel.Dispose();
        throw;
    }
}


private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<GolfStatTrackerEntities>().To<GolfStatTrackerEntities>().InRequestScope();
    kernel.Bind<IStatTrackerRepository>().To<StatTrackerRepository>().InRequestScope();            
}
Run Code Online (Sandbox Code Playgroud)

我不确定Ninject是否有问题,或者我是如何实现Ninject的.注入似乎正在处理Home视图的初始加载,但是,当它使用angular来调用API时,与Ninject断开连接.

请帮忙.

Bla*_*keH 5

我们最终在我们的一个旧项目上使用了类似的配置,并意识到我们需要为MVC/WebApi App添加更多基础设施代码:

NinjectDependencyScope.cs

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Web.Http.Dependencies;
using Ninject;
using Ninject.Syntax;

namespace YourAppNameSpace
{
    public class NinjectDependencyScope : IDependencyScope
    {
        private IResolutionRoot _resolver;

        internal NinjectDependencyScope(IResolutionRoot resolver)
        {
            Contract.Assert(resolver != null);
            _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.cs

using System.Web.Http.Dependencies;
using Ninject;

namespace YourAppNameSpace
{
    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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我们将以下内容添加到NinjectWebCommon.cs文件中:

public static void RegisterNinject(HttpConfiguration configuration)
        {
            // Set Web API Resolver
            configuration.DependencyResolver = new NinjectDependencyResolver(Bootstrapper.Kernel);

        }
Run Code Online (Sandbox Code Playgroud)

然后是以下的Global.asax.cs文件,Application_Start方法:

NinjectWebCommon.RegisterNinject(GlobalConfiguration.Configuration);
Run Code Online (Sandbox Code Playgroud)

  • @ MTL323,您应该注意Web API 2项目可以使用以下nuget包:https://www.nuget.org/packages/Ninject.Web.WebApi/3.2.0并且您不必创建这些类 (2认同)
  • 添加Ninject.Web.WebApi包解决了我在API控制器中遇到的问题.谢谢! (2认同)