当前位置: 首页 > 编程语言 > C#

重复位码的设计模式-C#技巧分享

时间:2023-04-10 22:18:07 C#

设计模式/重复位码的C#技巧我有一个WCF服务,可以记录任何异常,然后将它们作为FaultExceptions抛出。我正在做很多重复,例如在每个服务方法中。try{//做一些工作}catch(Exceptionex){Logger.log(ex);//实际上是FaultException但你明白了。扔前;我正在寻找一种更优雅的方式,因为我在每个服务中剪切并粘贴了try/catch。我可以使用设计模式/C#技巧来使它更优雅吗?您在谈论AOP-面向方面的编程以下是我通过将“工作”作为lambda传递来实现的方法:publicpartialstaticclassAspect{publicstaticTHandleFaultException(Funcfn){}catch(FaultExceptionex){Logger.log(ex);扔;然后使用它:returnAspect.HandleFaultException(()=>{//调用WCF});还有其他方法可以实现相同的目标,甚至是一些商业产品,但我发现这种方法是最明确和灵活的。例如,您可以编写一个为您创建和部署客户端的切面:publicpartialstaticclassAspect{publicstaticTCallClient(Funcfn){using(varclient=...createclient...){);所以:returnAspect.CallClient(client=>{returnclient.Method(...);});然后您可以包装您通常想要应用的所有方面并创建一个主要方面。在我们的一个WCF服务中有一个类似的问题,我通过使用一个帮助委托解决了它:publicstaticvoidErrorHandlingWrapper(ActionDoWork){}catch(Exceptionex){Logger.log(ex);//实际上是FaultException但你明白了。扔;}}用法:publicvoidMyMethod1(){ErrorHandlingWrapper(()=>{//工作});}publicvoidMyMethod2(){ErrorHandlingWrapper(()=>{//工作});}你还是要重复包装,但是代码少了很多,你可以在一个地方修改try..catch中的逻辑。对于特定于WCF的内容,您可以考虑添加自己的ErrorHandler。这允许您在每次任何方法抛出异常时“注入”您自己的代码。您可以这样设置:serviceHost.Description.Behaviors.Add(newErrorHandlerBehavior());//添加你自己的ErrorHandlerBehaviourpublicboolHandleError(Exceptionerror){if(errorisCommunicationException){log.Info("Wcf遇到通信异常。");}else{//日志}returntrue;}publicvoidProvideFault(Exceptionerror,MessageVersionversion,refMessagefault){//在这里你可以像这样将任何异常转换为FaultException:if(errorisFaultException)return;varfaultExc=newFaultException(error.Message);varfaultMessage=faultExc.CreateMessageFault();fault=Message.CreateMessage(version,faultMessage,faultExc.Action);}publicvoidAddBindingParameters(ServiceDescriptionserviceDescription,ServiceHostBaseserviceHostBase,Collectionendpoints,BindingParameterCollectionbindingPara米){}publicvoidApplyDispatcherBehavior(ServiceDescriptionserviceDescription,ServiceHostBaseserviceHostBase){foreach(ChannelDispatcherBasechannelDispatcherinserviceHostBase.ChannelDispatchers){publicvoidValidate(ServiceDescriptionserviceDescription,ServiceHostBaseserviceHostBase){}}这还允许您抛出各种异常并将它们转换为失败异常,稍后由WCF正确处理,而无需修改业务层或应用try/catch代码并在模板中方法模式在那里进行转换,您可以使用C#的委托(或lambda)轻松实现它而无需继承。您可能想尝试AspectF(不是我的):http://www.codeproject.com/Articles/42474/AspectF-Fluent-Way-to-Add-Aspects-for-Cleaner-Main。这是OmarAl-Zabir的作品……Dropthings框架等的创建者。希望这对你有帮助。如果你只是抛出异常,那么异常会在调用堆栈的顶部传播,你可以避免在每个深层处理它,而只是在最顶层(可能的)级别捕获它并记录它。请记住,异常对象还包含堆栈跟踪。顺便说一下,如果你需要catch,记得在每一层都使用throw,这样调用堆栈不会受到影响,但在你使用它的方式中,它会。您还可以尝试订阅global.asax文件中的Application_Error事件。对于桌面应用程序,AppDomain有一个UnhandledException事件。通常,您可以编写一些异常处理程序来为您完成多余的工作:publicabstractclassExceptionHandler{///如果处理了异常则返回true;否则返回假。公共抽象布尔句柄(异常前);protectedvoidLog(Exceptionex){//在此处记录异常}}publicclassFileExceptionHandler:ExceptionHandler{publicoverrideboolHandle(Exceptionex){this.日志(例如);//尝试优雅地处理异常if(exisUnauthorizedAccessException){//在这里添加一些逻辑(例如封装异常)//...returntrue;}elseif(exisIOException){//这里的另一个逻辑//...returntrue;}//没有处理异常...returnfalse;}}publicclassProgram{privatestaticvoidMain(string[]args){try{//文件操作thrownewIOException();}catch(Exceptionex){if(!newFileExceptionHandler().Handle(ex)){//异常没有被处理,所以抛出异常throw;}}Console.WriteLine("结束");如果你的问题是关于如何使你当前的模式更快如果合作,您可以通过创建Snippet来重复样板代码。以上就是C#学习教程:重复位代码的设计模式/C#技巧分享。如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注——trylogtrylog本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: