I just went to a NETDA lecture, in which Jeffrey Richter spoke on major changes to versioning.
In Win32, we had DLL hell, where one dll with the same name could overwrite another dll of the same name in the windows directory, causing a previously working application to fail. The .NET Frameworks solved this problem by introducing strongly named assemblies; however, it introduced another problem called "Versioning Hell," because a library could not easily be updated since the CLR looked for an exact version match. There was a complex way to solve this problem through policy files; however, even engineers at Microsoft found this approach too difficult.
Microsoft has a new approach for Longhorn and Orcas (.NET v3.0), which divides assemblies into two categories, Platforms and Libraries. The classification dictates which version of an assembly, an application references, is loaded by the CLR.
The main difference between the two is that the CLR binds to the latest version of a platform assembly but attempts to bind to the same version of a library assembly that an application was compiled against (major & minor version must match;though, the highest build & revision is used for "servicing"). Because the latest version of platform assemblies are used, platforms assemblies must be assembly committed to backward compatibility.
One analogy Richter used is that platforms are to interfaces and libraries are to implementation. Platform assemblies should only really include abstract classes, interfaces and basic types, because of limited flexibility and the need for backward compatibility. Another limitation of platform assemblies is that they cannot reference types from other "library" assemblies--only platform assemblies. Platform assemblies are good for providing contractual interfaces and basic types for data interchange throughout the system across multiple libraries, app-domains and process. Libraries, which have more freedom to change, should contain actual implementation.
Most assemblies will or should be libraries. Microsoft discourages the use of platform assemblies. However, it makes sense for assemblies that behave like system APIs, such as providing access to a single shared resource in the computer.
There are actually three types of platform assemblies: System-wide, process-wide, and app domain-wide. The latter two support a feature called interim rollback, in case an application fails to work with a newer version of the assembly than it was compiled against. System-wide platform assemblies do not support interim rollback. An administrator can exclude a specific newer version of a non-SW platform assembly from being loaded if the application fails to run with that assembly; however, if an even newer version of that platform assembly is loaded, the application will bind to that latest version, because it was not specifically excluded. This is because it is probably the case the later version will have fixed the incompatibility caused by the prior version. So, both process-wide and app-domain platform assemblies can have different platform assemblies run on different processes and app-domains, respectively.
The CLR, of course, will be a machine-wide platform assembly. In a break from the present scheme, Longhorn will no longer support multiple CLRs. Every managed application will be forced to use the latest version of the CLR on the system.
As for the other WinFX APIs, Indigo is most likely to be build as libraries, although some abstract classes may be available in AppDomain platforms. Avalon Core will be machine-wide platform assembly, with much of the non-core Avalon Framework as app-domain platform assemblies. WinFS, I recall, will probably be available as app-domain platform assemblies as well. Aero (the shell) will be machine-wide platform assembly as much of the assembly wraps machine-wide Win32 dlls.
As for the possibility that applications using reflection may break on a newer version of CLR, the CLR team has purposely made reflection behave less predictably. For example, the order of members returned from Type.GetMembers() is randomized prior to being returned.
Whidbey is expected to include an Assembly attribute, AssemblyFlagsAttribute, which allows to developer to specify Library, AppDomainPlatform, ProcessPlatform, SystemPlatform, or Legacy to identify the versioning scheme the CLR uses to load a reference assembly.
One other interesting news is that Virtual PC may actually be included and integrated within Longhorn.
>>the CLR team has purposely made reflection >>behave less predictably. For example, the order >>of members returned from Type.GetMembers() is >>randomized prior to being returned
Huh??
Is this to force people to actually search through the members to find the one they want instead of assuming it is always #6?
If they really are doing this, it will slow down what is already an inherently slow operation. Adding any overhead ( randomizing ) to Reflection types of operations just "because", is not a good thing IMO.
Posted by: Paul | June 15, 2004 at 05:37 AM
You can easily ask for a member by name if you're looking for a specific known member. Iterating or indexing to find something like that is the wrong model, and the fact that some people believe it is a reasonable approach is probably why they are breaking it: you're pretty much gauranteed that member indexes will change with assembly versions, so depending on them is not only inefficient it's dangerous.
Posted by: BenWa | June 15, 2004 at 11:34 AM
BenWa --
It may not have been clear in my comment, but I agree with you on the right and wrong ways to find a method, I am just commenting on the suggestion that they would deliberately randomize it. Why would that be a good thing? It just sounds to me like overhead that is not needed, or as trying to solve a problem that may not ever exist.
Posted by: Paul | June 15, 2004 at 02:51 PM
You forgot "Framework Hell", although I guess Microsoft and everyone else is so, er, "Hell"-bent on convincing people that .NET 1.0 never existed that they've actually convinced themselves by now. Here at (insert name of large pharmaceutical corporation), we still deploy .NET 1.0 applications. And guess what happens when we make a .NET remoting call from a 1.1 client (say, a user who has .NET 1.1 installed but not 1.0, which forces the code to run under the 1.1 runtime), to a server with 1.0 installed? Exception-o-rama. And that's assuming the code even gets that far-- we typically get System.Data exceptions on the client before we even get anywhere near a remoting call.
So yeah, can't wait for "every managed application will be forced to use the latest version of the CLR on the system." Whee.
Posted by: Jeff Atwood | June 15, 2004 at 04:24 PM
cvcvc
Posted by: cvc | June 15, 2004 at 10:35 PM
Paul --
You're absolutely right that this is theoretically unnecessary overhead, but the problem is that not all developers do things in the theoretically correct way. If an approach (say, using typeof(foo).GetMembers()[6]) seems to work consistently this week on a dev's machine they may well be tempted to check it into their build system. If it happens to work on the test systems too, the company may well decide to ship it. If the next version of the assembly adds a new member that happens to change the index, the idiot who wrote the broken code in the first place frequently comes crying back to either the assembly vendor or Microsoft (which often collapses down to a single option) blaming them for breaking the application.
As a platform supplier, Microsoft has been dealing with this problem for a very long time and understands the pain. When you can't even make bug fixes because some application depends on the broken behavior it becomes very difficult to move ahead.
In the Everett release the .NET team was pitching SBS deployment as the silver bullet for this problem. It seems that they've given up on that approach, and it really isn't too surprising given the complexity it caused.
The only other solution is to try to provide interfaces that can remain backwards compatible over time and many versions. This doesn't just mean that the interface itself remains static, it means that the behavior of the calls in the interface remain consistent. By returning the member list in a random order they are ensuring that it is used for its intended purpose, discovery, and telling developers in an impossible to ignore way that they cannot depend on the ordering.
The bottom line is that it's not enough to just document the behavior and say, "You can't depend on this remaining true." If it works every time someone will start depending on it.
Posted by: BenWa | June 16, 2004 at 03:27 PM
As an application developer, not a OS developer, I usually look to an OS's API's to behave consistantly according to the spec. If I misread the spec, then it is my bug, not the OS's.
For instance, shared data in Threads. I cant tell you how many people have told me that there was a bug in an OS because they were using threads with unprotected shared data.
That is not the OS's designers responsibility IMO. If I am going to use a feature that says in the docs "Dont rely on order to be consistant because of ..." I expect the order to change at some point and I ccode for it. Especially if the api is something as "Advanced" as reflection.
I expect speed and conformance to the docs out of an OS. Dont try to protect me.
BTW, your last sentance "If it works every time, someone will start depending on it." is funny if read wrong.
Thanks for the comments.
Paul
Posted by: Paul | June 17, 2004 at 04:57 AM
HUH!!! WHAT!!!
You got to be kidding!!! the last guy's comment was right on target, Framework Hell.
The Orcas Dev Team is totally out of whack. If Jeffrey Ricters statement will eventually be the proposed solution, then that's going to be more hell than ever before!!!
Who is to say this belongs in a Platform and that in a Library one day, and then months later it should have been the other way around!!!
You got a bunch of elitest MCSD certification nitwits and the latest-hyped-software-method theorists running the show who haven't programmed (that is actually coded) anything substantial by themselves. All they can dream up is more problems than REAL-LIFE solutions.
This Orcas team must spend more time asking trick certification questions to each other and are completely clueless to the real world. Heck, believe it or not, old fashioned ASP 3.0 still works and there are more web sites running it with MORE features than ASP.NET sites.
Get your head out of the latest software design and architecture book and go out and actually program something that someone will actually use for once and you will see its a lot different that your so called best software practices and architecture.
Posted by: anon | February 18, 2005 at 03:16 AM
I know JeffreyR is a big name but his this idea of "platform" and "libraries" is the stupidest ever as anyone can tell. I'm just imagining how such a dumb idea came in to existance and got adopted by MS elites. My assumption is that they must have had a month worth of design meetings with 5+ people in the room, everybody debating everyone else. As jeffrey is just an contractor, he would have given to an hybrid idea that seems to satiesfy everyone in the meetings. I don't think he is as dumb as to make this decision totally by himself. It's also amazing to see how rest of the so-called smart MS programmers just follows in like a herd of lambs without any commenting or critisism. Grow up dudes and spread the fire before this non-sense actually gets in to the build.
http://www.shitalshah.com/blog/IsJeffRichterScrewingUpTheNetVersioning.aspx
Posted by: Shital Shah | April 18, 2005 at 03:56 PM
Microsoft's solution does seem stupid to me. They think they're saving developers hassle later on by 'protecting us' now -- but the truth is, this change in reflection has broken my application and now I have to release a new version. So much for protection.
And I'm not even relying on the index position of members -- I know that's stupid. I'm just relying on the order of the members being the same as they are defined in code. What's wrong with that? After all it's under MY control?!
I can't see that's any worse than hard-coding a member name in your code.
To think that Microsoft actually wrote some code to continually randomize the order of members in the background and thought this was a good solution just makes me very worried.
Posted by: John Wood | June 29, 2005 at 04:53 PM