CLR loading is really something that happens through native APIs, either using hosting APIs directly (eg. ICLRMetaHost), or indirectly via COM. You can do this in managed code (no need to actually write any native code) by using .NET's interop facilities.
So yes, you could write code that ran in CLR v2 which loaded CLR v4 and vice-versa.
I know we've got some code samples in the works, but I don't think they've been posted yet. Keep an eye on the
SxS category of the CLR team blog. The simplest way is to build a managed COM component using one version of .NET, and then instantiate it using COM-interop from another version
of .NET exactly as you would without SxS. Look for any samples for building and using COM components with .NET 2.0.
First a couple follow-ups from your original post after talking to some folks on the team. How exactly are you detecting whether there is any CLR >= version 2 on the machine? Since CLR v4 is intentionally hidden from the existing CLR v2 APIs, your code
may actually do the desired thing and detect NO clr installed. Also, we've improved the experience on this sort of failure by popping a dialog saying something like "this application requires CLR v2.0 in order to run - click here to download it". Not perfect
of course, but hopefully a helpful mitigation.
Now for your OS question. Yes - big picture removing OS support for a version of the framework is a BIG compat decision. Due to the problem of perfect compatability I discussed in the video, doing this at all is always going to be an issue - regardless
of our roll-forward policy (even if we did roll forward, as we did 1.1->2.0, large apps have historically been likely to break unfortunately). Windows has a similar philosophy in that they work hard to maintain compat, but know they can't be perfect and so
also rely on mitigations like compat labs and app-compat shims. We do the same thing - running the most popular .NET apps in our labs, and where it's advantageous including app-specific compat policy with a new .NET Framework release (take a look at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\AppPatch\v2.0.50727.00000
for example - it lists applications that are known to be incompatible with v2 and so should not roll-forward, we can do a similar thing in v4 where we can list apps that we've tested and know work with v4 and so should be rolled forward). This of course is
only helpful for the biggest most popular apps, but it's helpful nontheless. Also, OS upgrade boundaries change the compat formula a bit and may influence the policy we choose to apply. For example, it's possible that a future version of Windows will include
only CLR V4 but will be configured to roll v2 apps forward to V4 (we have not made any decisions about what we WILL do here, just intentionally kept this open as an option - these decisions are all controled declaratively by the upgrade policy in the registry).
The key thing we need to avoid is installing a new .NET Framework breaking some application that was previously working fine - upgrading the OS on that machine is a bit of a different equation.
Still far from perfect, I know. But the compat space is all about trade-offs between lots of different less-than-perfect options.
Hi Joe. In most cases that scenario is not something that can be solved with SxS. In particular, SxS requires a pre-existing isolation in the code - just like app-domains or different processes. Most of the time when depending on managed assemblies, the
code is tightly coupled at the level of managed code (sharing objects freely back and forth without any sort of marshalling/remoting, etc.), and so can't easily be separated by an isolation boundary (appDomain/runtime/process).
However, this sort of scenario (composable 3rd party components) is one of the main reasons why binary compatibility is still so important for the CLR. Just like with .NET 1.x->2.0, we fully expect assemblies compiled against .NET 2.0 to be loaded into
the 4.0 runtime. So most of the time, rolling an application forward to 4.0 that has dependencies on 2.0 assemblies should hopefully just work fine. One notable exception I discuss in the video is IJW assemblies (C++/CLI compiled without /clr:pure or /clr:safe)
- those will unfortunately either need to be recompiled or the application will have to be configured to disallow the V2 runtime from being loaded.
I can imagine some rare cases though where this could be useful (depending on, for example, code though a COM interface that is implemented in .NET 2.0 and doesn't work on 4.0). And the ASP.Net team does believe there is some value here. But it'll probably
be rare, and not a high priority scenario in 4.0.
Thanks for the feedback, that's an interesting scenario we were hoping was going to be pretty rare. There's no doubt there's a trade-off here between a number of different types of 'breaking changes', and the principle we're relying on in this case is that
we'd rather have an application refuse to run than run on a platform it hasn't been tested with and possibly behave poorly.
We did spend a lot of time discussing how we will support developers that want a different trade-off - i.e. are willing to take the risk of allowing their app to run on a future version of the framework without having tested it. This is one of the main
reasons we now support 2-part version numbers in config files. So, you can get almost what you suggest by adding <supportedRuntime version="v4.0"/> to your app's config (and if you really want ALL future versions, you could add v5.0, v6.0, v7.0, etc. - but
I wouldn't reccomend it, there's a reasonable chance a complex app tested only against V2 will NOT run well on some CLR released 10 years from now <grin>).
Anyway, I definitely agree with your point about needing to do a good job "getting the word out". I've forwarded your comments to the SxS team and we're discussing how best to document this and other potentially surprising behavior related to SxS.