【问题标题】:ASP .NET MVC Controller Injection issueASP .NET MVC 控制器注入问题
【发布时间】:2017-04-01 15:02:43
【问题描述】:

在我的 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;
    }
}

IHub 存储库

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

我不明白为什么它不起作用。

【问题讨论】:

  • 您在设置 Ninject 时是否偶然拼错了某些内容?该错误抱怨ISistemiHubRepository,您可以在此处看到:Injection of dependency ISistemiHubRepository into parameter repHub of constructor of type ResultController。它不是在抱怨IHubRepository
  • @CodingYoshi 抱歉,修正了文本;遗憾的是不是与错字相关的问题
  • 我感觉它与此有关:public HubRepository(DbContext curCtx) 因为它需要一个参数来实例化。做一个测试并在那里放置一个空的构造函数,看看错误是否消失,如果是,那么你知道这是问题所在。然后要解决此问题,您可能需要在绑定期间使用它:.WithConstructorArgument("curCtx", .new DbContext /*or whatever*/);
  • @CodingYoshi 我试过了,但现在我遇到了一个上下文问题,因为它不能在初始化时调用 this.Configuration.ProxyCreationEnabled = false;里加 18:this.Configuration.LazyLoadingEnabled = false;里加 19: ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 90;
  • 好的,所以问题与构造函数有关?这是另一个错误,因此您需要弄清楚如何修复它。

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


【解决方案1】:

错误消息已经说明了可能的问题。 由于相关代码没有使用任何模块,因此您可以忽略提及模块和模块加载 => 2) 和 5) 的选项。 由于您没有使用命名参数,因此您也可以忽略 4)

对于数字 1) => 缺少绑定,也有可能您有两个不同的 IHubRepository(在不同的命名空间中)并且还为其中一个创建了绑定,但不是您请求的那个。你有一个Hub.Dal.IHubRepository 的绑定,但也许ResultController 想要Foo.Bar.IHubRepository

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

【讨论】:

    【解决方案2】:

    我用了两天的时间,通过添加、更改和删除对 Ninject 的引用,更改代码等等......

    通过完全删除解决方案并从 TFS 获得新的、清晰的获取来解决。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多