A Challenge to Microsoft, Scott Guthrie

After reading Ayende’s latest post, and having run into few myself just this weekend (see System.Data.SqlClient.MetaType), I’d like to challenge Microsoft’s .NET efforts, and particularly Scott Guthrie’s group (since I have the most hope of them actually accomplishing this), to release a library/framework/module (something like ASP.NET AJAX, ASP.NET MVC Extensions, etc — on that scope) with the following statistics:

  • 0% ‘internal’ keyword usage
  • 0% ‘sealed’ keyword usage
  • 0% (or very few) ‘static’ keyword usage
  • 0% (or very few) ‘private’ methods (only private fields).

If this functionality is good enough for you, why isn’t it good enough for us!

Also, sometimes you guys make mistakes or do something not very good (we all do, I’m not pointing fingers), and having a most of those methods be ‘virtual’ would really help so that we can fix things when occasional mistakes occur.

This would help us folks in the field more than you know!

About Chad Myers

Chad Myers is the Director of Development for Dovetail Software, in Austin, TX, where he leads a premiere software team building complex enterprise software products. Chad is a .NET software developer specializing in enterprise software designs and architectures. He has over 12 years of software development experience and a proven track record of Agile, test-driven project leadership using both Microsoft and open source tools. He is a community leader who speaks at the Austin .NET User's Group, the ADNUG Code Camp, and participates in various development communities and open source projects.
This entry was posted in .NET. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • >> If this functionality is good enough for you, why isn’t it good enough for us!

    I feel your pain my friend!

    I’ve even challenged developers to open up their frameworks and got a good bit of feedback on the idea.

  • Chad,

    I agree on internals, statics and sealed.
    However, I wouldn’t want to see the guys at Microsoft exposing every (or most) private methods.

    I don’t care for their private members (that always sounds bad), I just want to know that I can mock the external stuff when I have to.

  • EbbTide

    What’s wrong with static members?

  • @Steven: shoot, forgot about that post when I posted this. Cheers.

    @Omer: Good point, but I guess I would caution making anything private (aside from member fields) unless you absolutely HAVE to. In a framework like ASP.NET MVC, I’m willing to be that almost no methods should be private.

    @EbbTide: In the context of building frameworks: Static members are bad because they can’t be mocked easily, they’re usually used for some type of singleton arrangement (think HttpContext.Current) which also undermines and thwarts testing, etc. Also, they can’t be overloaded or extended (usually) which limits a framework’s re-usability.

  • Chad,

    There are a many important aspects to encapsulation such as clarity, intent and simplicity. These will all be shattered when releasing frameworks with every method as public.

    The user will be extremely confused as he will be presented with an Intellisense box containing thousands of irrelevant methods and wouldn’t be able to use the API as documentation. (I follow Krzysztof Cwalina advice from “Framework Design Guidelines” on this subject)

    Besides that, making everything public would require the developers to think of every small private method (InitializeSQLProps()) as a grade A public method that people will use. This means much more time on API design => less frequent releases.

  • @Omer: I’m no spring chicken, I’ve built several released public API’s myself and every time I’ve done so I always ended up regretting most, if not all the places I made things private/internal.

    I’m not familiar with Krzysztof’s book, but if it was used to design things like the SqlClient API in the BCL, then I would advise not using that book as it doesn’t reflect good framework design.

    The answer to your “InitializeSQLProps()” problem is not that it should be made private/internal (perhaps protected), but that it should be moved elsewhere.

    I’m starting to think that marking things private/internal on a >PUBLIC< API is a code smell.

    As a public API writer, you can’t POSSIBLY think of all the ways in which your consumers will use your API. So while you may not make InitializeSQLProps public, ALL THE FUNCTIONALITY in that method SHOULD BE PUBLIC ALLY AVAILABLE ELSEWHERE.

    The problem is that all to often people make the contents of InitializeSQLProps private/internal and make it a critical-path function for much of the functionality of a given API and any would-be extender or overrider is just plain S.O.L. (as is the case in much of the BCL API).

  • Chad,

    I’m probably wrong about this case, as I’ve never written a public API.
    My objection comes from a world of plain OOD, where I believe encapsulation has and will always have its respected place.

    Breaking encapsulation often leads to confusion and later on misuse. If you declare everything public, how can you direct your users to do the right thing? (Really, I would love your advice on this one for a public project I am going to start in a few weeks)

    P.S. I still think this will lead to less frequent releases, though.

  • @Omer I’m not saying to break encapsulation, I’m saying that you should design your classes in such a way as to minimize the amount of ‘private’ things you are doing.

    In my experience, ‘private’ methods in public APIs tend to be dirty little bits of procedural code that glue two otherwise-poorly-designed components together. I’m guilty of this and it has caused my customers and other developers consuming that API no end of grief.

    In the ‘InitializeSQLProps’, this sounds like a big, ugly procedural method whose functionality could otherwise be accomplished with more elegance and reusability, such as declarative configuration or through a configuration API of some sort.

    So you see, my point is something like this: “If you feel the need to do something in a private method, there’s probably a better way to do it that doesn’t involve a private method and would allow for greater customization and re-usability/re-purposing of your API in the field.”

    I’m not saying “just make every private method public” and cluttering up your API, I’m saying “design in such a way that you no longer need that private method”

    If you really MUST have something that’s hidden or private, at least make it PROTECTED and VIRTUAL at that.

    Final thought: Your primary goal as an API writer should be to allow consumers of your API to use it to fit their purposes. Providing convenient functionality is #2 priority. You will NEVER be able to predict how your API will be used in-the-field, so you MUST allow for it to be used in ways you didn’t expect. This means that you should, to the maximum extent possible, allow consumers to override, extend, and even replace parts of your API.

    Using test-driven development (NOT testing after-the-fact, although that still provides some benefit) will help you to design with extensibility and replace-ability in mind. Using TDD, you necessarily FORCE yourself to think as a user, using your API in different ways than it was originally designed for

  • Chad,

    Point taken, thank you.

    Btw, When I wrote ‘InitializeSQLProps’ I was thinking of ‘SetSQLProps’ taken from a generated SubSonic class I was just working with which has no justification of being public. However I wouldn’t think of generated SubSonic classes as ordinary public API.

  • I do recommend Cwalina’s Framework Design Guidelines, it was pretty much required reading at a company I worked at where one of our deliverables for our product was an API. If covers items like naming, usage, and design guidelines. Such as, correct way to expose an event. Stuff we popped open Reflector to see how MS did it.

    I really don’t mind things being private, non-virtual, etc. As long as they program to abstractions and interfaces, I’m OK. The larger the public surface area of an API, the less useful it tends to be as a large surface area can hinder discoverability. Make interfaces/behavior public, implementations private, that’s fine by me.

  • I think it is a really bad idea, since for Microsoft exposing everything means freezing every little bit of API forever.

    And extensibility is not just “everything is public and virtual”.

    For example, in MbUnit internals there are certain interfaces that I am allowed to implement, but my implementation will never be used by MbUnit. There is no way to configure the class that uses these interfaces to load more then several hardcoded implementations. Even if everything was public, it would not have helped me, since there is no way to find this class instance and modify it’s collections.

    Also, the fascination with interfaces in .Net community makes people forget that testable interfaces with only a single implementation are just a way to overcome limitations of a framework — while I use it, I feel it to be an anti-pattern. No SPOT, no DRY. Should we really recommend a workaround as a best practice in API design?

    I would definitely prefer a way to mock File.ReadAllText over using the abstract reader factory or IoC — if we all we want now is read a text from file, I’ll follow YAGNI and KISS.

  • Andrey:

    Breaking changes have historically not been a problem for me, so I’m happy if API designers make breaking changes as long as there is a good benefit to the API.

    What has historically ALWAYS been a problem for me is that there is a bug or critical piece of functionality I need to override or change for a specific project, but that functionality is locked up inside an internal sealed class and I’m screwed.

    I agree with the Interfaces, but currently there’s no other way around it. So unless you’re advocating I dump C# and .NET and go with something like Ruby, I’m not sure what your point is, really.