So I want to prevent this scenario by some way like developer should not be able to commit their code until project build successfully in visual studio.
Your end goal of only having pushed commits that build and test successfully is a good goal, however preventing developers from creating local, unpushed commits that does not build and test successfully is not a valid means to achieve that. In some scenarios creating "failing" commits is essential and required.
So forget about restricting (local) commits while developers are working on some feature and focus on having good commits when they push them. As already mentioned you can (and should) use CI to enforce this, however that should not be the only mechanism used because a) it has a way too long feedback round trip time and b) fixing any commits after they are already pushed requires forced pushing1.
Luckily there already exists a program that does exactly what you need, git test
written by Michael Haggerty. This program lets you define one or more test commands (e.g. "dotnet test mysolution.sln"), and then you can run such a test against a range of commits.
The result for such a test run is saved in git notes, so that running a test on a commit already tested just fetches the cached result and takes less than 1 second.
So this should be your primary focus, get all developers to use git test
. Also add git test as a step to your CI pipeline.
1
Forced pushing has two aspects that has potential for problems, accidental discard of commits and that other developers need to "recover" from the changed remote branch.