- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我可能会简化或误解事情,所以如果这是一个非常愚蠢的问题,我想提前道歉。 :)
根据我看过的文档和代码,我的理解是,当使用简单注入(inject)器(在 4.3.0
上)调用 RegisterWebApiController
时,“一次性 transient 组件"对于类型为 ApiController
的所有类,应该禁止显示警告。
话虽如此,下面的代码抛出了一个无效的配置错误
public class SimpleInjectorConfiguration
{
public static void Configure(
Container container, HttpConfiguration configuration)
{
container.RegisterWebApiControllers(
configuration, Assembly.GetAssembly(typeof(TestController)));
//Register the other required classes
}
}
The configuration is invalid. The following diagnostic warnings were reported: -[Disposable Transient Component] is registered as transient, but implements IDisposable.
实际上没有一个 Controller 覆盖 IDisposable
方法,从我可以调试的内容来看,下面的代码片段(取自最新的 Simple Injector
source )应该被成功调用:
registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent,
justification:
"Web API registers controllers for disposal when the request ends during the " +
"call to ApiController.ExecuteAsync.");
令人困惑的是,当我用下面的代码修改 Configure
方法时,它确实成功地抑制了警告(即有效)。
public static void Configure(
Container container, HttpConfiguration configuration)
{
container.RegisterWebApiControllers(
configuration, Assembly.GetAssembly(typeof(TestController)));
foreach (var component in container.GetCurrentRegistrations())
{
component.Registration.SuppressDiagnosticWarning(
DiagnosticType.DisposableTransientComponent,
"Web API registers controllers for disposal when the request ends during " +
"the call to ApiController.ExecuteAsync.");
}
//Register the other required classes
}
更令人困惑的是,我们在许多其他项目中使用了 Simple Injector,并且警告抑制似乎在所有项目中都按预期工作,但这就是为什么我认为这是某种配置问题.我已经尝试比较这些项目以找出不同之处,但不幸的是我还没有想出任何东西。
TestController
代码定义为
[RoutePrefix("api/Test")]
public class TestController : ApiController
{
public IHttpActionResult GetTestString()
{
return Ok("Test String from Test Controller");
}
}
任何人都遇到过这种情况,或者可以阐明为什么会发生这种情况?谢谢!
感谢下面 Steven 提供的信息,我设法弄清楚问题是因为 SimpleInjector
库之间看起来不一致。
SimpleInjector
在 4.3.0
上运行,而 SimpleInjector.Integration.WebApi
在 3.1.0
上运行。将 SimpleInjector.Integration.WebApi
升级到 4.3.0
就成功了。
最佳答案
发生这种情况的最可能原因是因为您的 Web API Controller 同时实现了 IHttpController
和 IDisposable
,但没有继承自 ApiController
。
Web API 的 ApiController
基类在 的 SendAsync
方法中注册自身以进行处理(通过调用 RegisterForDispose
)。这确保了 Controller 将在请求结束时得到处置。
这就是为什么 Simple Injector 会抑制继承自 ApiController
的 Controller 上的诊断警告; Web API 将确保它们得到处置。
由于处置注册发生在 ApiController
内部,这确实意味着 Controller 只实现了 IHttpController
(但没有继承自 ApiController
) 永远不会被释放。这就是为什么 Simple Injector 仅在 ApiController
派生的情况下抑制此警告。
因此,您应该永远不要在您的 Web API Controller 上抑制此诊断警告,而不采取其他保证您的 Controller 已被处置的预防措施。
如果您的 Controller 没有有意义的处理逻辑,您应该从 Controller 中删除 IDisposable
接口(interface)。这消除了问题。 Controller 很少需要处理逻辑,因为您通常应该将其提取到其他服务; Controller 通常不应依赖于它自己创建的资源。
但是,如果该 Controller 确实需要处置,您可以覆盖其注册以成为 Lifestyle.Scoped
。这确保类型由简单注入(inject)器处理:
容器.RegisterWebApiControllers( 配置, Assembly.GetAssembly(typeof(TestController)));
container.Options.AllowOverridingRegistrations = true;
container.Register<MySpecialController>(Lifestyle.Scoped);
container.Options.AllowOverridingRegistrations = false;
或者,您可以仅在该特定 Controller 上抑制诊断警告,并烹制一个特殊委托(delegate)以确保其处置:
container.GetRegistration(typeof(MySpecialController)).Registration
.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent,
"We dispose manually.");
container.RegisterInitializer<MySpecialController>(c =>
Lifestyle.Scoped.GetCurrentScope(container).RegisterForDisposal(c));
关于c# - 简易喷油器 : RegisterWebApiController failing to suppress DisposableTransientComponent warning,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52082514/
我可能会简化或误解事情,所以如果这是一个非常愚蠢的问题,我想提前道歉。 :) 根据我看过的文档和代码,我的理解是,当使用简单注入(inject)器(在 4.3.0 上)调用 RegisterWebAp
在我的集成测试中,我使用的是我在正在测试的 Web API 项目中构建的同一个 SimpleInjector.Container。 但是组合根类中的这一行: container.RegisterWeb
我是一名优秀的程序员,十分优秀!