Coding Standards
Patterns & Structure
Separation of Concerns
Each layer of the application should maintain separation from our layers within the application. For our sites, this primarily means separating the business logic from the presentation. As such:
All views (MVC or Web Forms) should be written against separate objects (view models) instead of internal data objects.
Views or Code Fronts should contain limited logic, as that should be maintained in the Controller or Code Behind.
Controllers or Pages should be primarily focused on the logic of displaying user interaction. Business logic associated with user input should be kept separately in a service layer.
Read more: https://en.wikipedia.org/wiki/Separation_of_concerns
SOLID Principles
SOLID is a set of principles for writing better software. From Wikipedia:
S - SRP
Single responsibility principle: a class should have only a single responsibility (i.e. only one potential change in the software's specification should be able to affect the specification of the class)
O - OCP
Open/closed principle: “software entities … should be open for extension, but closed for modification.”
L - LSP
Liskov substitution principle: “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.” See also design by contract.
I - ISP
Interface segregation principle: “many client-specific interfaces are better than one general-purpose interface.”
D - DIP
Dependency inversion principle: one should “Depend upon Abstractions. Do not depend upon concretions.”
Read more: https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
DRY / Rule of Three
In order to limit repetition, Follow DRY (Don't Repeat Yourself) as much as possible. Do this by following the Rule of Three, which states that if you re-use a piece of code three times separately, then you should re-factor into a new method or pattern.
Read more: https://en.wikipedia.org/wiki/Rule_of_three_(computer_programming)
Read more: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
Dependency Injection
In order to properly support Inversion of Control, utilize dependency injection via StructureMap, where possible, when working with non-static classes. Interfaces should be preferred when utilizing dependencies, to improve testability
In MVC Controllers, utilize automated constructor injection to gain access to dependencies.
INSERT EXAMPLE HERE
Outside MVC Controllers, use ServiceLocator calls to gain access to an instance registered with the IoC Container
var productService = ServiceLocator.Current.GetInstance<IElectroluxProductService>();
Read more: https://en.wikipedia.org/wiki/Dependency_injection
Read more: https://en.wikipedia.org/wiki/Inversion_of_control
Project Dependency Graph
When adding to the solution, the current dependency graph should be considered when considering where to place classes. Projects have a general purpose, and when adding new dependencies between the projects, you should think about the affect on any web projects within the solution.
Object Initialization
Use the var & Object Initializer syntax, where possible, for readability and brevity.
var cat = new Cat { Age = 10, Name = "Fluffy" };
Utility & Helper Classes
Classes with names ending with Utility should be Static.
Classes with names ending with Helper should be used when a class instance is required to utilize the helper. Helpers should not have static methods.
Properties vs Methods
Only use properties to represent actual data, and do not hide complex logic behind getters
Use methods to represent actions, which may take longer, change state, or have side effects.
Extension Methods
Extension methods should only be used for classes which we do not control, such as classes from Episerver or Microsoft libraries. If we control the class, consider an instance method, or utilize a Utility or Helper class.
Extension methods should not directly contain business logic. Wrap this logic inside a service, utility, or helper class to prevent code duplication.
Null Checking / Return Types
When building methods, public methods should not return null, where possible. Use an alternate pattern, such as a Result object wrapper or empty objects. This limits null checking for any callers.