我可能是在简化或误解,所以如果这是一个愚蠢的问题,我想提前道歉。 :)
根据我所看到的文档和代码,我的理解是,当使用简单注入器(在RegisterWebApiController
上)调用4.3.0
时,对于所有ApiController
类型的类,应禁止显示“一次性瞬态组件”警告。 。
话虽如此,以下代码引发了无效的配置错误
public class SimpleInjectorConfiguration
{
public static void Configure(
Container container, HttpConfiguration configuration)
{
container.RegisterWebApiControllers(
configuration, Assembly.GetAssembly(typeof(TestController)));
//Register the other required classes
}
}
配置无效。报告了以下诊断警告:
-[Disposable Transient Component]被注册为瞬态,但是实现了IDisposable。
实际上,没有一个控制器会覆盖
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控制器同时实现了IHttpController
和IDisposable
,但没有继承自ApiController
。
Web API的ApiController
基类在其RegisterForDispose
方法中注册自己以进行处置(通过调用SendAsync
)。这样可以确保在请求结束时将处置控制器。
这就是为什么Simple Injector在从ApiController
继承的控制器上抑制诊断警告的原因。 Web API将确保将其处置。
因为要进行处置的注册发生在ApiController
内部,所以这确实意味着仅实现IHttpController
(但不继承自ApiController
的)控制器将永远不会被处置。这就是为什么Simple Injector仅在ApiController
派生的情况下禁止显示此警告的原因。
因此,在不采取其他保证保证控制器安全的前提下,切勿在Web API控制器上抑制此诊断警告。
如果控制器没有有意义的处理逻辑,则应从控制器中删除IDisposable
接口。这消除了问题。控制器很少需要处理逻辑,因为您通常应将此逻辑提取到其他服务中。控制器通常不应依赖于它自己创建的资源。
但是,如果确实需要处置该控制器,则可以覆盖其注册以成为Lifestyle.Scoped
。这样可以确保类型由Simple Injector处理:
container.RegisterWebApiControllers(
配置,Assembly.GetAssembly(typeof(TestController)));
container.Options.AllowOverridingRegistrations = true;
container.Register<MySpecialController>(Lifestyle.Scoped);
container.Options.AllowOverridingRegistrations = false;
或者,您可以仅在该特定控制器上取消诊断警告,并烹饪一个特殊的代表以确保将其丢弃:
container.GetRegistration(typeof(MySpecialController)).Registration
.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent,
"We dispose manually.");
container.RegisterInitializer<MySpecialController>(c =>
Lifestyle.Scoped.GetCurrentScope(container).RegisterForDisposal(c));
关于c# - 简单的注入(inject)器:RegisterWebApiController无法抑制DisposableTransientComponent警告,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52082514/