I’ve noticed that a lot of developers define an interface for EVERY class that is going to be injected using DI framework. What are the advantages of defining Interfaces for every class?
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
Letting your application components (the classes that contain the application logic) implement an interface is important, since this promotes the concept of:
This is effectively the Dependency Inversion Principle (DIP). Doing so allows you to replace, intercept or decorate dependencies without the need to change consumers of such dependency.
But still, the DIP is not the only principle to consider. In many cases developers will be violating other parts of the SOLID principles (DIP is one out of five SOLID principles) when having primarily one-to-one mappings between classes and an interfaces in their applications. One of the principles that is almost certainly violated in that case is the Open/closed principle, because when every class has its own interface, it is not possible to extend (decorate) a set of classes with cross-cutting concerns (without dynamic proxy generation trickery that is).
In the systems I write, I define two generic interfaces that cover the bulk of the code of the business layer. They are called
ICommandHandler<TCommand>and anIQueryHandler<TQuery, TResult>:Besides the nice side effect of not having to define many interfaces, this allows great flexibility and ease of testing. You can read more about it here and here.
Depending on the system I write, I might also use interfaces such as:
IValidator<T>for validating messagesISecurityValidator<T>for applying security restrictions on messagesIRepository<T>, the repository patternIAuthorizationFilter<T>for applying authorization/security filtering onIQueryable<T>queries.Depending on the system I write, somewhere between 80% and 98% of all components implement one of these generic interfaces I define. This makes applying most cross-cutting concerns to those so called joinpoints trivial.