I see some classes in the .net framework that support reading and writing, saving and loading, classes whose main responsibility is not them, for instance the Stream classes and the XML Dom/XLinq classes.

closed as too broad by gnat, Martin Maat, Robert Harvey, David Arno, Eric King Jul 17 '17 at 23:06

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    I'm not sure what your question is. – Mike Harris Jul 17 '17 at 18:29
  • I think if you focused this question on one of the classes, I'd be willing to up-vote (I wasn't the down-voter). – Greg Burghardt Jul 17 '17 at 22:46
  • The problem with this question is it assumes the so-called SOLID principles are a positive thing. I am not saying the the .net framework is well designed in all aspects, but SOLID usually leads to overly complex designs, which no one really wants. – Frank Hileman Jul 19 '17 at 2:25

Let's touch on these one by one.

S is for Single Responsibility

  • The single responsibility for XMLDocument is to provide APIs for traversing an XML document
  • Yes, its interface has methods for saving and loading, but the implementation of XMLDocument doesn't actually save or load. It parses or unparses with respect to a abstraction, a "stream," which you'd have to supply to the XMLDocument in order for those methods to work. Parsing and unparsing is naturally associated with traversal. Persistence isn't handled by the class itself.
  • Stream and StreamReader/Writer classes also do this. They work on logical representations, a theoretical infinite byte array, which is actualized in one of the subtypes, such as a MemoryStream or FileStream.

O is for open/closed

Moot. All framework classes are closed to modification, unless you are doing something really weird.

L is for Liskov Substitution

Pretty sure you can substitute any type of stream when a steam is needed; whoever is using the stream generally won't care if it's a stream that goes to memory, to disk, or to a network connection. If there are differences in capability (e.g. a maybe a network stream doesn't provide random access) those capabilities are discoverable via properties in the base class, e.g. CanSeek.

I is for Interface Segregation

Microsoft has been a bit slow on providing interfaces for many of its classes. That being said, you can easily write code that works with abstract base types instead of concrete types, e.g. you can write code that works with any type of stream as long as it inherits from BaseStream.

D is for Dependency Inversion

XMLDocument and the stream classes both use dependency injection, following the principle of inversion of control. In fact StreamReader and StreamWriter are two of the earliest examples of this principle, since they take the underlying stream as a constructor argument (via a stream's abstract base implementation, which is as good as accepting an interface). XMLDocument uses DI by allowing an abstract base stream to be injected as a method argument to Save or Load.

So no, I don't agree with you, I think the .NET framework does a decent job of following SOLID.

  • I certainly agree it does a good job generally, especially in newer parts of the framework, but the oldest parts of the framework have some very Un-SOLID examples such as DataGrid – Ben Cottrell Jul 17 '17 at 19:10
  • What is it about DataGrid that troubles you? – John Wu Jul 17 '17 at 19:28
  • Dear is for "Dependency inversion", not for Dependency injection. Big difference. Injection is an approach you use to follow inversion principle – Fabio Jul 17 '17 at 21:11
  • It's hard to imagine anything in Winforms that could be held up as a model for SOLID. Nevertheless, the rest of the framework is, er, solid. – Robert Harvey Jul 17 '17 at 21:31
  • 1
    The most obvious example of where the framework laughs in the face of SOLID is with the NotImplementedException and NotSupportedException and the whole mess around IReadOnlyList inheriting from IList. Oh and all those static IO classes, and all those side-effect classes that don't implement interfaces... but aside from all that, yeah it's reasonably solid (if you don't lean on it too much...) – David Arno Jul 17 '17 at 22:25

Not the answer you're looking for? Browse other questions tagged or ask your own question.