我在 Owin Selfhosted 中使用 Simple Injector,但我在调用
container.Verify()
时遇到问题。
当我调用
container.Verify()
时,它正在创建我所有控制器的一个实例,但在我的一些控制器中我有一些规则,并且根据配置它会抛出一个错误,说你不能使用路由。基于此,我只能在调用端点时创建控制器的实例。
这是我的启动代码:
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
Monitor.VerifyConfingurations();
ManipulateHttpConfiuration(config);
app.UseWebApi(config);
var container = ContainerGerenciador.NovoContainer();
ConfigureDI(container, config);
if (debug)
{
config.EnableSwagger(c => {
c.SingleApiVersion("v1", "Swagger WSLinear API");
c.IncludeXmlComments("WSLinearApi.XML");
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
c.UseFullTypeNameInSchemaIds();
}).EnableSwaggerUi(x=>
{
x.DisableValidator();
});
}
var options = new FileServerOptions
{
EnableDefaultFiles = false,
DefaultFilesOptions = { DefaultFileNames = { "index.html" } },
StaticFileOptions = { ContentTypeProvider = new CustomContentTypeProvider() }
};
app.UseFileServer(options);
}
private void ConfigureDI(Container container, HttpConfiguration config)
{
#region Register
container.Register<ILinearLogger>(
() => new Logger(new LinearLoggerConfiguration()
{
Path = PathFinder.GetLogsFilePath()
}),Lifestyle.Transient);
container.Register<IMyService,MyService>();
Integrations.Setup.Register(container);
#endregion
container.RegisterWebApiControllers(config);
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
container.Verify();//here the error is thrown
}
控制器示例:
[RoutePrefix("api/SampleIntegration")]
[SwaggerResponse(HttpStatusCode.BadRequest, "Business Logic error", typeof(BusinessExceptionResponse))]
[SwaggerResponse(422, "Invalid Entity", typeof(CamposInvalidosExceptionResponse))]
public class SampleIntegrationController : ApiController
{
private readonly IMyService _myService;
public SampleIntegrationController(IMyService myservice)
{
_myService = myservice;
if(!_myService.IntegrationEnabled())
throw new BusinessException("Sample Integration is not enabled! Enable it to access the route.")
//above the error is thrown because simpleInjector creates an instance of this controller before the route is accessed
//but I only this exception to throws only when the route is accessed (if the integration is not enabled)
}
[HttpGet]
public HttpResponseMessage Get()
=> CreateResponse(() => _myService.GetData());
//...
}
我试图删除
container.Verify()
行,但是当调用第一个端点时它会抛出相同的错误(它创建所有其他控制器的实例)。
我该怎么做才能使 Simple Injector 在从实际路由调用之前不创建我的控制器实例?
随着版本 5 的推出,Simple Injector 会自动验证您的对象图,即使您没有显式调用
Verify
。此功能称为自动验证,可以关闭。您可以做的是将验证移至单元或集成测试,如 Simple Injector 文档中 here 所述。
虽然这是一个可能的解决方案,但我认为您应该为您的控制器考虑不同的验证策略。
正如您已经注意到的那样,在您的构造函数中包含此逻辑会导致困难,其中包括:
相反,请考虑以下替代方案:
ActionFilter
或 DelegatingHandler
在每个调用的控制器操作之前关闭。这将验证逻辑保留在控制器之外,并允许在构造对象图后进行验证。IMyService
创建一个装饰器,以确保在调用 IMyService
时触发验证。如果控制器调用大量服务,此解决方案可能不太方便,因为您将为所有服务实现装饰器。另一方面,当您的控制器仅依赖于几个通用接口时,例如 command handlers 和 query handlers,您只需为每个通用接口实现一个控制器,这可能会使该解决方案更可行。