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?
相关问题
- Wrapping Angular components which has Parent/Child
- How to map interface names to different method nam
- Union of two object bags in Java
- Should this property be part of my object's in
- How to I access the DbContext of EF core from anot
相关文章
- List可以存储接口类型的数据吗?
- When to use Interfaces in PHP
- Can Eclipse auto-generate an interface of a 3rd pa
- Implementing interfaces in partial classes
- Injecting an IEnumerable into a constructor with a
- ASP.NET Core DbContext injection
- DI container, factory, or new for ephemeral object
- How does @Inject in Scala work
This blog entry has a lot of the answers you are looking for: http://benpryor.com/blog/2006/08/23/java-advantages-of-interfaces/
If you don't design to interfaces, you are going to be hamstrung when it comes time to refactor your code and/or add enhancements. Using a DI framework is not really at issue when it comes to designing to an interface. What DI gives you is late-binding and much better ability to write unit tests.
Letting your application components (the classes that contain the application logic) implement an interface is important, since this promoted the concept of:
This is effectively the Dependency Inversion Principle. Doing so allows you to replace, intercept or decorate dependencies without the need to change consumers of such dependency.
In many cases developers will be violating the SOLID principles however when having an almost one-to-one mapping between classes and an interfaces. One of the principles that is almost certainly violated 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% procent of all components implement one of these generic interfaces I define. This makes applying cross-cutting concerns to those so called joinpoints trivial.