简体   繁体   English

简单 RestApi 的这个 c# 代码有什么问题?

[英]What is wrong in this c# code for simple RestApi?

I received feedback:我收到反馈:

"code test is not at the expected level there's a lack of understanding of async, HTTP clients, and just software development patterns in general. Poor structure and testing" “代码测试未达到预期水平,缺乏对异步、HTTP 客户端以及一般软件开发模式的理解。结构和测试不佳”

The simple test and solution are on GitHub https://github.com/sasa-yovanovicc/weatherapi简单的测试和解决方案在 GitHub https://github.com/sasa-yovanovicc/weatherapi

I'll really appreciate any help to understand what is wrong because the code works, the test works,, and covers all solutions, and honestly, I don't know what they expect.我真的很感激任何有助于理解问题所在的帮助,因为代码有效,测试有效,并且涵盖所有解决方案,老实说,我不知道他们期望什么。

I understand that in OOP code can be more abstracted and complex, but I can't see any purpose in making code more complex than needed to solve a given problems.我知道在 OOP 中代码可以更抽象和更复杂,但我看不出使代码比解决给定问题所需的更复杂的任何目的。

There are few improvements which can be made, that will not only follow modern practices, but simplify the code in some cases:可以做的改进很少,不仅会遵循现代实践,而且在某些情况下会简化代码:

  1. Use IHttpClientFactory (previously instantiating HttpClient per request was considered a bad practice - see here and here why, though now situation was improved, also see this ).使用IHttpClientFactory (以前根据请求实例化HttpClient被认为是一种不好的做法 - 请参阅此处此处为什么,尽管现在情况有所改善,但也请参阅)。 For possible usage patterns check the docs有关可能的使用模式,请查看文档

  2. Use strongly-typed configs for example with options pattern使用强类型配置,例如使用选项模式

  3. There is literally no reason to use GetAwaiter().GetResult() in your code, for example in WeatherController :实际上没有理由在您的代码中使用GetAwaiter().GetResult() ,例如在WeatherController中:

     if (response.IsSuccessStatusCode) { var weatherResponse = response.Content.ReadFromJsonAsync<WeatherResponse>().GetAwaiter().GetResult();

In my view, code can be improved in this area:在我看来,可以在这方面改进代码:

  1. This piece of code should be placed in Service layer .这段代码应该放在Service层 This code is placed in AstronomyController这段代码放在AstronomyController

     HttpClient httpClient = new(); var responseAstro = await httpClient.GetAsync(requestURIAstro);

    Usually, controllers should not have any logic.通常,控制器不应该有任何逻辑。 It should coordinate and orchestrate services.它应该协调和编排服务。

  2. If this Helper class has the StringHelper name, it will be more readable:如果这个Helper class 有StringHelper名称,它将更具可读性:

     public class StringHelper

    So it can be concluded that if StringHelper would have code snippet that will contain code which helps to work with int type, then it would be violation of Single Responsibility Principle of SOLID principles .因此可以得出结论,如果StringHelper的代码片段将包含有助于使用int类型的代码,那么它将违反SOLID 原则单一责任原则。

  3. Using GetResult() can be a potential reason of a deadlock使用GetResult()可能是死锁的潜在原因

    var r = response.Content.ReadFromJsonAsync<ErrorResponse>().GetAwaiter().GetResult();

    So it is better to use await :所以最好使用await

     var r = await response.Content.ReadFromJsonAsync<ErrorResponse>(); // the other code is omitted for the brevity
  4. It is better to write tests by triple A pattern .最好按三重 A 模式编写测试。 In addition, try to use abstractions when you will write code for controllers.此外,在为控制器编写代码时,尽量使用抽象。 Read more about how to test controllers here 在此处阅读有关如何测试控制器的更多信息

    Eg:例如:

     public class HomeController: Controller { private readonly IBrainstormSessionRepository _sessionRepository; // the other code is omitted for the brevity

    Here IBrainstormSessionRepository is an abstraction.这里IBrainstormSessionRepository是一个抽象。 Moreover, read this article " Unit testing best practices with .NET Core and .NET Standard " is very helpful.此外,阅读这篇文章“ Unit testing best practices with .NET Core and .NET Standard ”非常有帮助。

  5. Multiple Assert should be avoided in tests.测试中应避免使用多个Assert There is a very nice book by Roy Osherove's "The Art of Unit Testing". Roy Osherove 的“The Art of Unit Testing”有一本非常好的书。 One of the things that Osherove warns against is multiple asserts in unit tests. Osherove 警告的事情之一是单元测试中的多个断言。 That is, one should generally avoid writing tests that can fail for more than one reason.也就是说,人们通常应该避免编写可能因不止一种原因而失败的测试。

    Eg, here should be just one Assert :例如,这里应该只有一个Assert

     Assert.NotNull(result); Assert.IsType<ObjectResult>(result); var objectResult = result as ObjectResult; Assert.NotNull(objectResult); var model = objectResult.Value as InfoMessage; Assert.NotNull(model);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM