如何在使用Autofac WcfIntegration时处理构造函数exception
有没有办法处理WCF服务的构造函数抛出的exception,当该构造函数接受依赖项时, 它是IoC容器(在本例中为AutoFac)导致exception的依赖实例化 ?
考虑具有以下构造函数的WCF服务:
public InformationService(IInformationRetriever informationRetriever) { _informationRetriever = informationRetriever; } //... the service later makes use of the injected InformationRetriever
该服务使用AutoFac WcfIntegration和AutofacWebServiceHostFactory
(这恰好是一个RESTful服务)。
依赖关系在服务的global.asax.cs中注册,即:
builder.RegisterType() .As()
现在, InformationRetriever
实现在其构造函数中执行一些检查,以确保一切就绪,以便能够完成其工作。 当它在此阶段发现问题时,它会抛出exception。
但是,我不希望服务的调用者接收AutoFacexception:
An exception was thrown while invoking the constructor ... on type InformationRetriever
我有效地试图测试:
鉴于 InformationService正在运行
当我调用GetSomeInformation()方法时
并且无法实例化InformationRetriever
然后我想返回一个友好的错误消息
并记录实际的exception
这是我的设计问题,还是有一个已知的模式来克服或防止这个问题?
我一直在寻找,无法找到有关此类问题的任何信息。
我不是构造函数的忠实粉丝,因为除了错误的参数之外的其他原因抛出exception。 我可能会以不同的方式为我的类型建模。 但这里有一些想法。 起初我想过做这样的事情:
builder .Register(c => { try { return new InformationRetriever(); } catch (Exception) { return new FailoverInformationRetreiver(); }}) .As();
…其中FailoverInformationRetreiver
在成员访问时抛出exception。 另一个想法可能是:
public InformationService(Lazy informationRetriever) { _informationRetriever = informationRetriever; }
并try/catch
InformationService
用法。 如果在应用启动时已知InformationRetriever
的可用性,您可以使用另一个选项:
// inside your container builder: if (InformationRetreiver.IsAvailable()) builder.RegisterType() .As() // inside InformationService, make the dependency optional public InformationService(IInformationRetriever informationRetriever = null) { _informationRetriever = informationRetriever; }
这些想法有帮助吗?
以DI风格编写的对象通常通过两个独立的阶段:组合和执行。 组合阶段是连接依赖项并执行抛出参数exception等操作的地方。 您通常希望保持此阶段没有有意义的行为,因为这样可以在系统配置中显示错误。 第二阶段是执行,您可以使用第一阶段(依赖项)的输出来完成工作。
分离这两个阶段消除了很多模糊性和复杂性。 举个例子,你不要试图在给割草机放气的同时修剪草坪; 这导致两个活动变得更加复杂(并且危险!)
在这种情况下, InformationRetriever
通过在其构造函数中执行有意义的工作来混合组合和执行阶段。 这种混合正是导致您要避免的问题:一个有意义的业务exception被包装在一个组合exception中。 还不清楚如何处理exception,因为顶级调用程序是Autofac而不是实际要求InformationRetriever
执行工作的组件。
我建议在调用InformationRetriever
时努力进行validation; 这将删除Autofacexception并允许InformationService
在没有任何欺骗的情况下处理exception情况。
这种方法的一个潜在缺点是validation将在每次调用InformationRetriever
时发生,而不是在构造函数中发生一次。 你有两个选择:1)让它每次都发生,绝对确定工作是否有效,或者2)跟踪你是否已经完成检查,只有你以前没有做过。
如果选择#2,则可以通过使用装饰器将其包装在同一接口的validation版本中来保持InformationRetriever
清洁:
public class ValidatingInformationRetriever : IInformationRetriever { private readonly IInformationRetriever _baseRetriever; private bool _validated; public ValidatingInformationRetriever(IInformationRetriever baseRetriever) { _baseRetriever = baseRetriever; } public void Foo() { if(!_validated) { Validate(); _validated = true; } _baseRetriever.Foo(); } private void Validate() { // ... } }
您可以使用Autofac的装饰器支持注册它,如下所示:
上述就是C#学习教程:如何在使用Autofac WcfIntegration时处理构造函数exception分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
builder .RegisterType() .Named("base"); builder.RegisterDecorator ( (c, inner) => new ValidatingInformationRetriever(inner), fromKey: "base");
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/983203.html