We are currently having a big debate internally around the usage of Uri and String
in our APIs.
Use Uri not String
URI cannonicalization and escaping is very complex and people always get it wrong,
so you must have a single codebase to do the work. Beyond that, converting from each
form of a URI can introduce artifacts, so once you resolve (my shorthand for canon,
escape, etc.) the URI you can really never go back to a string and try to resolve
again (not precisely true, but basically). In Internet Explorer the resolving of URIs
was a huge source of security issues, so we can't repeat that mistake in WinFS.
Offer both Uri and String
Using a single codebase for resolving URIs is great, just don't make developers suffer
by having to create URIs everywhere. Developers think of URIs as strings, not complex
objects.
The pattern should look like:
class MyComponent {
void SetSomething(string uri);
void SetSomething(Uri uri);
Uri GetSomething();
}
The idea being that developers can call either version of the API. The implementation
of SetSomething(string) would do nothing more than new up a Uri and call SetSomething(Uri).
Use Uri not String
The problem with the above pattern is that in a component based system you have people
calling components through multiple layers. If internal MSFT develoepers (and third
party component developers) start calling the string version, we get back into the
"string -> uri -> string -> uri" world which introduces loss of data (hence
security issues).
Offer both Uri and String
We should just have a rule that says once you convert a Uri to a string, never go
back. Then developers on the leaf of a component hierarchy would do the conversion,
and it would transfer back.
Use Uri not String
Ahh, that is a great view, however history has shown us that doesn't work. It isn't
possible to guarantee that no one converts back to a string, and therefore we will
ship a bunch of components with this.
... And the debate continues to rage...