I have been reading that creating dependencies by using static classes/singletons in code, is bad form, and creates problems ie. tight coupling, and unit testing.
I
They're fine as long as you design them well ( That is, you don't have to change their signature from time to time).
These utility methods do not change that often, because they do one thing only. The problem comes when you want to tight a more complex object to another. If one of them needs to change or be replaced, it will be harder to to if you have them highly coupled.
Since these utility methods won't change that often I would say that is not much problem.
I think it would be worst if you copy/paste the same utility method over and over again.
This video How to design a good API and why it matters by Joshua Bloch, explains several concepts to bear in mind when designing an API ( that would be your utility library ). Although he's a recognized Java architect the content applies to all the programming languages.
You could always create an interface and use that with dependency injection with instances of classes that implement that interface instead of static classes.
The question becomes, is it really worth the effort? In some systems, the answer in yes, but in others, especially smaller ones, the answer is probably no.
I really, really try to avoid them, but who are we kidding... they creep into every system. Nevertheless, in the example given I would use a URL object which would then expose various attributes of the URL (protocol, domain, path and query-string parameters). Nearly every time I want to create a utility class of statics, I can get more value by creating an object that does this kind of work.
In a similar way I have created a lot of custom controls that have built in validation for things like percentages, currency, phone numbers and the like. Prior to doing this I had a Parser utility class that had all of these rules, but it makes it so much cleaner to just drop a control on the page that already knows the basic rules (and thus requires only business logic validation to be added).
I still keep the parser utility class and these controls hide that static class, but use it extensively (keeping all the parsing in one easy to find place). In that regard I consider it acceptable to have the utility class because it allows me to apply "Don't Repeat Yourself", while I get the benefit of instanced classes with the controls or other objects that use the utilities.
This really depends on the context, and on how we use it.
Utility classes, itself, is not bad. However, It will become bad if we use it the bad way. Every design pattern (especially Singleton pattern) can easily be turned into anti-pattern, same goes for Utility classes.
In software design, we need a balancing between flexibility & simplicity. If we're going to create a StringUtils which is only responsible for string-manipulation:
=> Utility classes, themselve, are not bad. It's the developers' fault that make it bad.
It all really depends on the context. If you're just gonna create a utility class that only contains single responsibility, and is only used privately inside a module or a layer. Then you're still good with it.
Use them sparingly, you want to put as much logic as you can into your classes so they dont become just data containers.
But, at the same time you can't really avoid utilites, they are required sometimes.
In this case i think it's ok.
FYI there is the system.web.httputility class which contains alot of common http utilities which you may find useful.
From a theoretical design standpoint, I feel that Utility classes are something to be avoided when possible. They basically are no different than static classes (although slightly nicer, since they have no state).
From a practical standpoint, however, I do create these, and encourage their use when appropriate. Trying to avoid utility classes is often cumbersome, and leads to less maintainable code. However, I do try to encourage my developers to avoid these in public APIs when possible.
For example, in your case, I feel that UrlParser.ParseUrl(...) is probably better handled as a class. Look at System.Uri in the BCL - this handles a clean, easy to use interface for Uniform Resource Indentifiers, that works well, and maintains the actual state. I prefer this approach to a utility method that works on strings, and forcing the user to pass around a string, remember to validate it, etc.