203

Reluctance to modify code for the sake of testing shows that a developer hasn't understood the role of tests, and by implication, their own role in the organization. The software business revolves around delivering a code base that creates business value. We have found, through long and bitter experience, that we cannot create such code bases of nontrivial ...


115

Checking for uniqueness and then setting is an antipattern; it can always happen that the ID is inserted concurrently between checking time and writing time. Databases are equipped to deal with this problem through mechanisms like constraints and transactions; most programming languages aren't. Therefore, if you value data consistency, leave it to the expert ...


75

It's not as simple as you might think. Let's break it down. Writing unit tests is definitely a good thing. BUT! Any change to your code can introduce a bug. So changing the code without a good business reason is not a good idea. Your 'very thin' webapi doesn't seem like the greatest case for unit testing. Changing code and tests at the same time is a bad ...


39

I think what you call “fail fast” and what I call it is not the same. Telling the database to make a change and handling the failure, that is fast. Your way is complicated, slow and not particularly reliable. That technique of yours is not fail fast, it is “preflighting”. There are sometimes good reasons, but not when you use a database.


23

.NET Framework is a VM, a JIT compiler, an object memory system consisting of a memory allocator and a garbage collector, a loader, a linker, and a runtime system (collectively called the Common Language Runtime (CLR)) which executes and supports a language called Microsoft Intermediate Language (MSIL). It is also a class library called the Base Class ...


18

Designing code to be inherently testable is not a code smell; on the contrary, it is the sign of a good design. There are several well-known and widely-used design patterns based on this (e.g., Model-View-Presenter) that offer easy (easier) testing as a big advantage. So, if you need to write an interface for your concrete class in order to more easily test ...


16

This started as a comment but grew too large. No, as the other answers have stated, this pattern should not be used.* When dealing with systems that use asynchronous components, there will always be a race condition where the database (or file system, or other async system) may change between the check and the change. A check of this type is simply not a ...


13

It is IMHO very simple to understand that for creating unit tests, the code to be tested must have at least certain properties. For example, if the code does not consist of individual units which can be tested in isolation, the word "unit testing" does not even start to make sense. If the code does not have these properties, it must be changed first, that is ...


12

I take issue with the (unsubstantiated) assertion you make: to unit test the Web API service we will need to mock this factory That's not necessarily true. There are lots of ways to write tests, and there are ways to write unit tests that don't involve mocks. More importantly, there are other kinds of tests, such as functional or integration tests. Many ...


11

HTTP doesn't work like that. The client sends a request, then the server sends a response back. No other communication occurs. Well, the server can send 1xx informational responses before the main response. But there is no way for the client to send updates about a sent request. (The situation is very different for HTTP/2 which can multiplex multiple ...


10

Your question talks about repositories being IQueryable (i.e. classes implementing the IQueryable interface), whereas your linked resource talks about repositories returning IQueryable objects. That's not the same thing. For the purpose of this answer, I'm going to assume you misspoke and meant to focus on repositories returning IQueryable objects. What is ...


10

You are in luck as this is a new project. I've found that Test Driven Design works very well for writing good code (which is why we do it in the first place). By figuring out up front how to invoke a given piece of code with realistic input data, and then get realistic output data which you can check is as intended, you do the API design very early in the ...


8

If you need to modify to the code, that is the code smell. From personal experience, if my code is difficult to write tests for, it's bad code. It's not bad code because it doesn't run or work as designed, it's bad because I can't quickly understand why it is working. If I encounter a bug, I know it's going to be a long painful job to fix it. The code is ...


8

In general DI should be supported in libraries. The actual implementation or selection of a DI Container should not be done by a library, that should be left to the root application. That way the root application can decide on whether or not to use DI what DI library to use which other dependencies to load/pass on to the library DI support can be ...


7

The purpose of verifying the email address is to obtain proof that the owner of the email address and the user who registered are the same person. It therefore follows, that the logical thing to do if an email address remains unverified for a significant length of time, that the user who registered is not actually the owner of that account, or you have ...


6

I suggest you to read a great book about the C# dependency injection by Mark Seemann, with a lot of real world samples for different tasks you can do with it, even with circular dependencies similar to your case. In general, the main design rule is You can't resolve the problem on its level, and in this case it's true too. You really need a mediator here to ...


6

Extension methods are just syntactic sugar for ordinary static method calls. Extension methods make possible the ability to "spot-weld" methods onto existing types, without requiring inheritance, composition, weaving or any other language mechanisms. But they're just a proxy for an ordinary method call; they don't participate in the design of the ...


6

There's a number of advantages to transient controllers. I cannot tell you whether any of them were the reason they were done that way - speculating about the intent of designers does not make a good SE question. (As a side note, controllers aren't exactly transient, because by default they're not created by the DI container at all.) One, this allows the ...


5

In my view there is rarely a good case for a shared project. The main reason is versioning and change control. If you recompile source code, then strictly speaking you have a new version. Its not so much of an issue in these days of build servers and ci. But some of us will remember when building on a devs machine and copying to production was a normal ...


5

Yes .Net Core although still very new, is suitable for rapid web development. Caveat #1 : Asp.Net MVC/WebApi is the more mature technology. You may find it more compatible if you are doing lower level type operations. Caveat #2 : You are always faster programming in the way you know. It sounds to me like you were making too big a jump on a project with ...


5

When dealing with style, it is always more useful to take either an official style if one exists, or to use the one commonly adopted by the community of developers writing in a specific language. You're lucky, for C#, there is an official style created by Microsoft. Another good thing is that Microsoft also developed a tool called StyleCop which checks if ...


5

Essentially you are describing a mapping of Role to Permission. I think this is pretty much covered by the standard [Authorize(Role=xxx)] on your controller actions, where the implied permission is CanExecuteThisAction. No need for extra policies as they would simply act as a mapping, potentially confusing the issue and as you say, adding a lot of ...


5

Paging is an implementation detail. DDD concerns itself mostly with architectural design; it doesn't have much to say about how you handle page breaks, since handling concerns like paper size or screen length is not part of the business domain, although it can be a part of the design process. Where should you put your paging? Where it is most convenient ...


5

Pagination is not a domain concern. The domain layer typically does not care to know the number of records fetched from a persistence store. It is a performance concern, specifically on the database side. And the only domain elements that deal with the database are repositories. So the way I see it, you need a mechanism to send it from the API request (or ...


5

If the purpose is to display on a page the first step is to limit the amount of data returned. No one can process 3 million rows at once, find ways to limit the data returned. Requiring search criteria or only returning X rows per page can drastically speed up performance with no real impact to usability. Ensure you are using SQL to create the result set, ...


5

If you want to return a meaningful error message you'll probably want to add validation. Every application I've worked on has done some request validation and returned an error message before attempting to process the request. This helps client developers or users retry with correct data instead of calling first line support complaining something is broken. ...


5

In genereal it's not a good idea. There are exceptions however. An access log can be implemented with a database, GET being a safe http method should never change the resource, but access log is not the resource so that is ok. If you need to integrate with some system that doesn't understand the semantics of http (PLCs i'm looking at you) you can be forced ...


5

how do we test the public service methods in such a way that we don't have to duplicate the code/effort that we have already spent in testing the internal/private/helper methods? Don't unit test your internal/private/helper methods, problem solved.


5

Is it a bad practice to use X whenever possible? Yes. It is bad practice to turn off your brain and lean on absolutes. It's far better to understand why. So lets step back from that framework and try to find a more useful one. The reason for this, they claim, is because singleton ensures that code is thread-safe. Oh how wonderful it would be if we could ...


4

I would actually advise against doing that. Sharing a database - any kind of database - between multiple applications is pretty much coupling central, and you can find yourself in a very tough spot down the line when any kind of schema changes are required. There's actually an anti-pattern for this - the Integration Database (https://martinfowler.com/bliki/...


Only top voted, non community-wiki answers of a minimum length are eligible