Avoid DevPath

I hesitate to talk about this because I don’t want people who don’t know about it to think, “Hey, what’s this DevPath thing? I need that.” But, maybe if I don’t explain how to use it, it will be too much effort for people who don’t already know how. 🙂 (And, for those who already know how and are, in fact, using it, hopefully, they’ll see this and get off that plan.)

The intent of DevPath was to make the development environment less painful. Assemblies could be put there and bound to at runtime, ignoring the assembly version and overriding the GAC.

It turns out that that’s badness for several reasons (below). So, DevPath is soon to be deprecated. Don’t use it – not even in the development environment.

Why It Should Never Be Used
Versioning alone is why you should never, ever use it in a production environment. It subscribes your users to dll hell. See Avoid Partial Binds for details (DevPath causes partial binding, since the version is ignored for the bind).

It’s not good for the dev. env., either – it makes it unnecessarily different from the shipping env., which may lead to uncaught versioning or deployment bugs in the shipping env.

What to Do Instead
If DevPath was a development environment-only solution for you:
I strongly recommend not changing your assembly versions between non-shipping builds instead of using DevPath.

If you are shipping code relying on DevPath:
One thing you could do is create a new AppDomain with the ApplicationBase set to the path you care about. Once you do that, see Executing Code in Another Appdomain.

If there are multiple paths you want to load assemblies from, use PrivateBinPath or multiple AppDomains. If that’s not reasonable for you, consider using the LoadFrom context.

Comments (16)

  1. Yosi Taguti says:

    Suzanne hi,
    great blog…
    I tried to use devpath in 1.0 but didn’t succeed , I even posted this on the newsgroups but no one answered,
    how do enable devpath?

    I disagree with you on the "Why It Should Never Be Used"
    I think it should never be used on the QA machines, and that way you’ll avoid deploying devpath enabled programs and get into an un familiar environment when you go production.

    did mean that devpath will no longer exist in whidbey?

  2. Kevin Westhead says:

    I agree with Suzanne on this, it’s too easy to get into trouble with DEVPATH and I’ve always avoided using it for that reason. I can see why it’s useful during development as a time-saver, but ultimately I don’t think it’s good pratice.

    Wrt enabling DEVPATH, what did you try? AFAIK if the environment variable is correctly set then you just need a config file with developerInstallation set to "true".

    Deprecated means that it will be removed in a "future" version, although typically this translates to the next major release after it has been deprecated. I would guess that if it is being deprecated in v2 then it will be removed in v3, although I could be wrong.

  3. John Lyon-Smith says:

    I agree with you on the non-use of DEVPATH, and I’m glad to see it’s being deprecated. I think you’re perhaps giving the wrong message on the non-use of the assembly version number during development. I see what you’re saying, but I think as if you encourage people to stop incrementing version numbers we’re just gonna descend back into "assembly hell".

  4. Suzanne says:

    Yosi: Yes, we’re pushing for it to be deprecated for Whidbey. In fact, it was never ‘supported’ – it was only documented because we doc everything. So, it’s not surprising that it wasn’t working (correctly) for you, even if you correctly enable it.

    John: Changing versions to fix assembly hell only works for shipping time. For development time,if you have someone taking drops of your daily builds, they’re going to want the new stuff – they won’t want to continue to bind against the old drop (otherwise, why take a drop?). That means that they will rebuild and/or re-config in order to run the new stuff – breaking changes and all. So, they will get the exact same assembly hell whether you change your versions or not, because they will run against the new code, regardless of its version.

  5. Anthony Berglas says:

    Great Blog.

    But it is a problem with .Net that this assembly / version documentation is scattered in blogs and news groups. It is obviously too subtle for technical writers to understand.

    It would be really wonderful to have this information gathered together in one, (farily large), serious document. How does this versioning really work?

    The best I’ve found is Jeffrey Richter’s book, and that is only superficial.


  6. Suzanne says:

    Thanks, Anthony. There are articles in MSDN which cover this (search for "version", for example). But, it’s hard to cover everything in just one article. Usually, they take one viewpoint, and cover the interesting information from that viewpoint. For example, if someone is new to .NET, they’re probably not ready for the nitty-gritty details about special cases in something they don’t need to use.

  7. Leonardo B. Postacchini says:

    Hello there!

    There is an week or so I am pretty much drowned in the Assembly Hell. I (and my team) am working in an application and it has lot´s of assembly´s, each time I recompile a building block in my machine, there comes it all again. Everething stop´s working.

    No, I am lying, everething builds OK, It´s when I try to run something that the head ache begins.

    I lost a lot of time to figure what was happening, then I thogth I found the answer, I made an UML Package chart to keep track of what depends on what and a bath to copy all dll´s to the same place, remove all of then from the Assembly and replace all with the new build components. Each time I build any assembly, I go down the tree rebuilding, putting all in the assembly cache and then rebuilding the assemblies that depends on the rebuilded assembly and so on until I reach the topmost app´s.

    And it didn´t worked, I still get error loading assemblies and now I found that APPHELP.DLL is needed for one of my(in some time on the past funcional) assembly that references only to System, System.Data and System.XML cannot load. Small surprise, it cannot be found anywere in my computer. But, the same assembly, inside the project when it´s called by the test app I allways build to test each piece of the application, works just fine.

    Can you save me? Or am I a sinner that deserves this hell and my destiny is to be tortured with devpath?


    P.S.: I did not post my mail address cause it´s probably full, for I am overtiming at the work and without time to clear it. Thanks Again.

  8. Suzanne says:

    From what I can tell from your description, it sounds like you are changing your assembly versions for each build. You can avoid the problems you describe by not doing that – only change after each shipping (non-development) version. See http://blogs.msdn.com/suzcook/archive/2003/05/29/57148.aspx for more information.

  9. Kevin I says:

    Hello – We are looking getting our .Net deployment straightened out and I’m confused as to why this is a bad idea. We hate the GAC idea because we have a nice deployment (internal) for our Com stuff and want to roll .net in there and use it like XCopy (or com). We do not want to support the additional overhead/headaches of versioning — we have a dev/qa/production type of rollout which works great.

    The devpath is the simple answer to our problem – avoiding the GAC. The alternative would be putting an override in the machine.config for all of our .net components (for servers), and generating an app.config with all of the .net components to redirect to our ‘component folder’ on startup. While the two method mentioned aren’t too evil, the devpath would just be set once for all machines and then be done — no continual regeneration of .config files needed.

    What is this about deprecation? Is it really going to be removed?

    Kevin I

  10. Bryan Mau says:

    I was humored to see that when you search on "devpath" in Google it makes the suggested correction:

    Did you mean: death

  11. Eric Brown says:

    The GAC did nothing but create another level of dll hell. Previoslly as long an objects Interface/API did not change a new version of a dll would not cause a problem, but now all this version crap as to match or .Net throws a a fit. We now actually have to put out a dll file for for every previous version of or dll that does nothing to but maps to the new dll so that customers that developed agains the older version continue to work after an upgrade. Managing the GAC in dev when dealing with debuging an previous version, on the same computer new dev is being done is pain in the rump. In the end the GAC causes us more pain then dll hell did because we tightly control the interfaces so dll hell is not an issue except through our .Net api, (all are api just wrapper interfaces to our common core code).

    I hate the GAC

  12. Suzanne says:

    Eric: I think there’s a misunderstanding here. The GAC is no worse than the old method of overwriting the old file with the new one. That’s because you could always not change the assembly version, and install it into the GAC, overwriting what’s already there, to get that same behavior. Then, all old references would automatically pick it up – no policy or anything required. In fact, that’s what I recommend for the dev (non-shipping) case in the link I gave, above, in this very blog entry.

    However, for the shipping case, you usually would not want to do that (see that same link), because of dll hell. The GAC is a nice thing, then, because then both versions can be available, to provide more flexibility for apps sharing that component. If you decide to set policy, it only needs to be done once, at ship time, which is minimal pain for a major benefit (solving dll hell).

    Keep in mind, also, that controlling interfaces does not actually solve dll hell. You would also have to prevent any behavior changes, or else risk breaking apps dependent on it. In practice, that’s unworkable. There are always bug fixes that end up breaking something, despite good intentions, even if no new bug is introduced. (Apps may have actually depended on the behavior of the original bug.)

  13. john smith says:

    this blog posions the mind of people who don’t realize that suzanne cook doesnt know what she’s talking about.

    for better info on devpath, i suggest reading

    particularly the comment that says

    At the time of her blog, we briefly considered deprecating DEVPATH, and replace it with something else. The decision was reverted and we fully support DEVPATH in development mode.

    The ultimate authority is MSDN. If MSDN does not say it is deprecated, it is not deprecated. “

  14. suzcook says:

    ‘John’ (I presume that’s not your real name): That blog entry was correct at the time I wrote it (in 2003). However, it is true that plans can change over time. Note that the blog entry you gave does not dispute the reasons I gave against the use of DevPath (other than because it was on the chopping block). For those reasons, I still consider it better to deprecate it if the breaking change committee will allow it (apparently, it may not).

    Kevin: Like I suggested in my original entry, for your case, I recommend not changing your assembly versions between non-shipping builds instead of using DevPath. That avoids having to update .configs while avoiding the disadvantages of DevPath.