ASP .NET MVC控制器注入问题

时间:2017-04-01 15:02:44

标签: c# asp.net-web-api dependency-injection ninject

在我的ASP .NET MVC WebApi项目中,我有接收参数的控制器构造函数,我没有无参数构造函数。

使用Ninject注射家属:

  • Ninject 3.2.0.0(3.2.2)
  • Ninject.Web.Common 3.2.0.0(3.2.3)
  • Ninject.Web.WebApi 3.2.0.0(3.2.4)

当我调用API时,我得到:

  

发生了'Ninject.ActivationException'类型的异常   Ninject.dll但未在用户代码中处理

     

其他信息:激活IHubRepository

时出错      

没有匹配的绑定可用,并且该类型不可自我绑定。

     

激活路径:

     

2)将依赖关系IHubRepository注入参数   ResultController类型的构造函数的repHub

     

1)请求ResultController

     

建议:

     

1)确保您已为IHubRepository定义了一个绑定。

     

2)如果在模块中定义了绑定,请确保该模块   已被加载到内核中。

     

3)确保您没有意外创建多个内核。

     

4)如果使用构造函数参数,请确保参数   name与构造函数参数名称匹配。

     

5)如果使用自动模块加载,请确保搜索路径   和过滤器是正确的。

代码如下。

控制器:

public class ResultController : BaseHubController
{
    public ResultController(IHubRepository repHub)
    {
        _rep = repHub;
    }

    public async Task<IHttpActionResult> Get(string fileName)
    {
        if (String.IsNullOrEmpty(fileName))
            return BadRequest();


        return Ok();
    }
}

NinjectResolver

public sealed class NinjectResolver : NinjectScope, IDependencyResolver
{
    private IKernel kernel;

    public NinjectResolver(IKernel kernelParam)
        : base(kernelParam)
    {
        kernel = kernelParam;
        AddBindings();
    }
    public IDependencyScope BeginScope()
    {
        return new NinjectScope(kernel.BeginBlock());
    }

    public void AddBindings()
    {
        kernel.Bind<Hub.Dal.IHubRepository>().To<Hub.Dal.HubRepository>();
        kernel.Bind<System.Data.Entity.DbContext>().To<Hub.Dal.Context>();
    }
}

public class NinjectScope : IDependencyScope
{
    protected IResolutionRoot resolutionRoot;
    public NinjectScope(IResolutionRoot kernel)
    {
        resolutionRoot = kernel;
    }
    public object GetService(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).SingleOrDefault();
    }
    public IEnumerable<object> GetServices(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).ToList();
    }
    public void Dispose()
    {
        IDisposable disposable = (IDisposable)resolutionRoot;
        if (disposable != null) disposable.Dispose();
        resolutionRoot = null;
    }
}

IHubRepository

public interface IHubRepository
{
    bool LogRequest(SHApiLog logData);
}

HubRepository

public class HubRepository : IHubRepository
{
    private DbContext _ctx;

    public HubRepository(DbContext curCtx)
    {
        this._ctx = curCtx;
    }

    public bool LogRequest(SHApiLog logData)
    {
        try
        {
            _ctx.Set<SHApiLog>().Add(logData);
            _ctx.SaveChanges();
        }
        catch (Exception)
        {
            return false;
        }

        return true;
    }
}

我无法理解为什么它不起作用。

2 个答案:

答案 0 :(得分:1)

错误消息已说明可能存在的问题。 由于相关代码没有使用模块,您可以忽略提及模块和模块loading =&gt;的选项。 2)和5)。 由于您没有使用命名参数,因此您也可以忽略4)

对于数字1)=&gt;缺少绑定,还有可能你有两个不同的IHubRepository(在不同的命名空间中),并且还为这些中的一个创建了绑定,但没有为你请求的创建绑定。您对Hub.Dal.IHubRepository具有约束力,但ResultController可能需要Foo.Bar.IHubRepository

要检查多个内核,您可以使用服务定位器 - 将IKernel(或IResolutionRoot)注入Controller而不是IHubRepository。在控制器构造函数和NinjectResolver的控制器内设置断点。点击第一个断点时,在内核引用上设置对象ID。点击第二个,检查是否有对象ID,是否相同。如果不是......那么你就有了多个内核。

答案 1 :(得分:0)

通过添加,更改和删除对Ninject的引用,更改代码等等,我把头撞了两天。

解决方案是完全删除解决方案,并从TFS获得新的明确获取。

可能代码中某处有一个讨厌的引用;我很难过。