发生了奇怪的事情:在我的网络 api 中,我在使用 Ninject 解析时将一个存储库注入(inject)到 Controller 中。存储库存储在私有(private)只读成员变量中。工作得很好!当一个 api 方法被调用时,我访问了这个变量 - 只是发现它突然变成了 null!
伪例子:
public class MyController : ApiController {
private readonly IRepo _repo;
public MyController(IRepo repo) {
Guard.AgainstNullArgument("repo", repo); // guarding to
// make sure it's not null
// (would throw ex)
_repo = repo; <--- successfully injected
}
// calling this method
public HttpResponseMessage TestMethod() {
_repo.. <--- suddenly null
}
}
我已经将问题追溯到一个微小的细节: Controller 中的一个方法(不是被访问的方法)用一个自定义属性进行了注释,该属性指示 ninject 以一个工作单元拦截该方法。如果我取消该属性,一切都会神奇地再次起作用。
UnitOfWorkAttribute.cs
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface)]
public class UnitOfWorkAttribute : Attribute
{
}
AttributeInterceptionStrategy.cs(用于ninject)
StartupConfig.cs(组合根、IoC 配置等)
EfUnitOfWorkInterceptor.cs
public class EfUnitOfWorkInterceptor : SimpleInterceptor
{
private readonly IUnitOfWork _unitOfWork;
public EfUnitOfWorkInterceptor(IUnitOfWork unitOfWork)
{
Guard.AgainstNullArgument("unitOfWork", unitOfWork);
_unitOfWork = unitOfWork;
}
protected override void AfterInvoke(IInvocation invocation)
{
if(!_unitOfWork.Commited)
_unitOfWork.Commit();
_unitOfWork.Dispose();
}
}
编辑
我确实在各处都设置了断点以弄清楚发生了什么。在 Controller 上创建一个析构函数以确保整个类不会被垃圾化,并将只读成员更改为具有 getter/setter 的属性,我在 setter 上断点以检查它是否被分配了两次。没有任何可疑的事情发生。
编辑 2
堆栈
Ninject.Extensions.Interception.dll!Ninject.Extensions.Interception.Injection.Dynamic.DynamicMethodInjector.Invoke(object target = {EIT.Management.Configuration.Web.Api.Controllers.SetupGroupController}, object[] arguments = {object[2]}) Unbekannt
Ninject.Extensions.Interception.dll!Ninject.Extensions.Interception.Invocation.Invocation.CallTargetMethod() Unbekannt
编辑 3*
最佳答案
真奇怪!我想也许你有另一个构造函数没有设置你的_repo,然后是一个由它实例化的 Controller 的新实例。
关于c# - 私有(private)成员在 API 方法调用中突然为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27802634/