none
Shared Assemblies: Before we start RRS feed

  • General discussion

  • I manage a project, I am responsible for a multi component class library and some tools/apps that also use the class library, the library is intended also for customers (developers/end users) to use.

    The system installs via a setup project (we also use SmartAssembly as obfuscation tool), this all works fine on various editions of Windows.

    For past few years we have built this up as based on private assemblies, this was very convenient, easy to debug, test and supply beta builds to customers etc.

    Now we need to step up the quality here in terms of deployment for customer use in the real world, as we move from beta to a more stable and settled production stage, and I have some questions before I start to make changes.

    Right now everything is part of one large solution.

    1. Will our testing/debugging become more difficult or awkward once libraries are signed?
    2. Will our installer (a setup project) install stuff in GAC by itself (I see an option in setup project for this)?
    3. Will Add/Remove programs (after we install) automatically remove stuff from GAC?
    4. During development (when we never run an install) does VS 2008 automatically put libraries in GAC after builds?
    5. If not, how do debugged apps find/load the signed libraries?
    6. Should we force 'Copy Local' to be OFF once we start referring to signed assemblies?
    7. Should visual studio add-ins also be signed?

    I am perusing Programming .Net Components (Juval Lowy, 2003 edition) about this aspect of .Net but want to get a feel for probable/possible hurdles before we start, I dont want to screw up my entire productivity and development setup on my box, simply because I hastily jumped into this without planning.

    Any info, suggestions, web artciles etc will be much appreciated.

    Thx
    Cap'n

     


    Monday, October 5, 2009 7:06 AM

All replies

  • Please ask only one question per thread.  Other than signing the assemblies, there is no reason to change anything on your dev machine.  The GAC is purely a deployment choice.  Ask questions about it at the Setup and Deployment forum.

    Hans Passant.
    Monday, October 5, 2009 8:44 AM
    Moderator
  • Well my questions span setup, deployment, visual studio, add/remove programs and so on.

    To post them as separate posts is just ineffieicient surely?

    You did answer one of them with "Other than signing the assemblies, there is no reason to change anything on your dev machine."

    Well I'm puzzled, right now several projects in the solution have references to the assembly DLLs in their various locations.

    If we tell VS 2008 to sign these assemblies, then does it automatically put those assemblies in the GAC when it builds OR must we continue to set references to the locally generated assembly DLLs (which will now be signed).

    You see if VS does not put them into the GAC, then our eventual setup project will build a setup for apps that refer to those local copies. BUT we want the setup to put the assemblies in the GAC and we want the installed apps to refer to these, but if our projects (app projects) refer to local copies then the whole thing will become a mess.

    Thanks

    H


    Monday, October 5, 2009 2:24 PM
  • Nothing is automatic here.  Putting an assembly in the GAC on your dev machine is pointless.  You cannot reference assemblies in the GAC, the exact path is not discoverable.  You always reference a copy of the assembly when you compile.  The copies of the .NET assemblies are in c:\windows\microsoft.net for example.  Again, the GAC is a deployment detail.

    Hans Passant.
    Monday, October 5, 2009 4:46 PM
    Moderator
  • Nothing is automatic here.  Putting an assembly in the GAC on your dev machine is pointless.  You cannot reference assemblies in the GAC, the exact path is not discoverable.  You always reference a copy of the assembly when you compile.  The copies of the .NET assemblies are in c:\windows\microsoft.net for example.  Again, the GAC is a deployment detail.

    Hans Passant.

    Thanks for mentioning this, but I am now more puzzled.

    So why install my products assemblies to the GAC at all?

    I was under the impression that VS allowed me to set references to shared libraries in the GAC, but it seems not.

    So we have all this effort by MS to streamline and increase efficiency yet we end up needing two copies of ever DLL?

    How does VS 2008 populate the .Net tab in the Add Refereence dialog?

    Must I install my product to both the GAC and some other folder, so that there are TWO copies?

    This all sounds very confusing and messy to me.

    H
    Tuesday, October 6, 2009 7:12 AM

  • >So why install my products assemblies to the GAC at all?

    To save disk space, speed up loading time, have a single copy you need to service etc.

    >So we have all this effort by MS to streamline and increase efficiency yet we end up needing two copies of ever DLL?

    Only on the dev machines. The GAC is used when you deploy.

    >How does VS 2008 populate the .Net tab in the Add Refereence dialog?

    It lists the content of the framework diretory and some additional folders you can specify in the Registry.

    How to display an assembly in the "Add Reference" dialog box

     

     


    Mattias, C# MVP
    Tuesday, October 6, 2009 8:13 AM
    Moderator

  • >So why install my products assemblies to the GAC at all?

    To save disk space, speed up loading time, have a single copy you need to service etc.

    >So we have all this effort by MS to streamline and increase efficiency yet we end up needing two copies of ever DLL?

    Only on the dev machines. The GAC is used when you deploy.

    >How does VS 2008 populate the .Net tab in the Add Refereence dialog?

    It lists the content of the framework diretory and some additional folders you can specify in the Registry.

    How to display an assembly in the "Add Reference" dialog box

     

     


    Mattias, C# MVP

    Thanks for this info, I appreciate it, every bit helps!

    I am forming the opinion that this relationship between the GAC and Visual Studio is broken.

    It is ridiculous that we should have two copies of libraries, given that these are always identical too.

    One should be able to refer to a GAC assembly just as they would any other assembly, it is ridiculous that we have to add registry keys in order to have product components appear in Visual Studio.

    Even SharpDevelop can do this.

    H
    Tuesday, October 6, 2009 9:39 AM
  • given that these are always identical too.
    That's where you are missing the point of the GAC, it was specifically designed to deal with the case where they are *not* identical.  The GAC allows deploying many different versions of your DLL, it solves DLL Hëll.  So you can maintain your code and send the customer an update that won't break old programs that you don't want/need to update.  This is very visible on your own machine, you can have multiple versions of the .NET runtime installed.

    Hans Passant.
    Tuesday, October 6, 2009 11:41 AM
    Moderator
  • given that these are always identical too.
    That's where you are missing the point of the GAC, it was specifically designed to deal with the case where they are *not* identical.  The GAC allows deploying many different versions of your DLL, it solves DLL Hëll.  So you can maintain your code and send the customer an update that won't break old programs that you don't want/need to update.  This is very visible on your own machine, you can have multiple versions of the .NET runtime installed.

    Hans Passant.
    I am not misisng the point.

    I am ware that the GAC serves that purpose.

    What is stupid is that a component vendor must install TWO copies of their library assemblies, one in the GAC (which will be loaded at runtime) and one in a proprietary folder, that must also be defined in the registry that allows the assembly to be seen in Visual Studio's Add Reference dialog.

    Thus for a single assembly delivered for developer use, we must actually store and track TWO copies, one in the GAC and another in some folder, that is stupid.

    What if these get out of synch accidentally? it will be a real pain.

    VS 2008 should be able to reference assemblies directly in the GAC, the fact that is can't is a handicap, there is no sound design behind this.

    Like I said above, SharpDevelop does let you set a reference to GAC assemblies, this has been missing since the earliest days of managed code.

    H



    Tuesday, October 6, 2009 2:49 PM
  • I don't know exactly how or what SharpDevelop is doing, but I think VS actually got it right, given how the GAC is designed. The fact that the GAC stores its content on disk is an implementation detail. There's no GAC API for getting the file path of one of its assemblies. All you get is the assembly name, which you can then pass on to the loader. So it would be wrong for VS to make any assumptions about where in the file system a particular GAC assembly is stored. Who knows, in the next version the assembly could be in a database, in "the cloud" or somewhere else.

    Mattias, C# MVP
    Tuesday, October 6, 2009 3:35 PM
    Moderator
  • Hi,
    If you want to get better understanding of .net framework programming, following books are worth to read:
    Applied Microsoft® .NET Framework Programming
    CLR via C#

    Thanks,
    Eric

    Please remember to mark helpful replies as answers and unmark them if they provide no help.
    Monday, October 12, 2009 2:08 AM
  • Also there is one very important reason for having 2 versions of the same DLL on developer machines:
    Developers mostly want to develop and build their applications against different versions (usually RTM) than those installed on their machine (latest SP).

    Imagine this situation: You release assembly Library.dll (let's call it RTM version). Later you create a hot fix/service pack which introduces a new public class 'NewClass' in this assembly.
    Another developer using your Library may install latest service pack of your Library, but what if he/she develops application against the RTM version? What if he doesn't want to force all their users to jump right on the latest service pack of your Library?
    It becomes even worse: What if the developer doesn't remember which version of Library.dll is really installed in his GAC? If such developer would build against Library.dll in GAC, then he doesn't really know whether he can use NewClass from your Library or not. He would have to carefully remember.

    In other words, what you deploy on machine for execution and what you use for development should be distinct. You will avoid a lot of unwanted dependencies and mess this way. Having 2 copies of the same assembly on developer machines is perfectly fine and desirable.

    -Karel

    Thursday, October 15, 2009 10:05 PM
    Moderator
  • > must install TWO copies

    Meditate on the meaning of "cache".  ;-)

    That said, there are numerous things about assembly loading, including the GAC, that I don't like.  Oh well, not much can be done about it...
    Friday, October 16, 2009 12:15 AM
  • Also there is one very important reason for having 2 versions of the same DLL on developer machines:
    Developers mostly want to develop and build their applications against different versions (usually RTM) than those installed on their machine (latest SP).

    Imagine this situation: You release assembly Library.dll (let's call it RTM version). Later you create a hot fix/service pack which introduces a new public class 'NewClass' in this assembly.
    Another developer using your Library may install latest service pack of your Library, but what if he/she develops application against the RTM version? What if he doesn't want to force all their users to jump right on the latest service pack of your Library?
    It becomes even worse: What if the developer doesn't remember which version of Library.dll is really installed in his GAC? If such developer would build against Library.dll in GAC, then he doesn't really know whether he can use NewClass from your Library or not. He would have to carefully remember.

    In other words, what you deploy on machine for execution and what you use for development should be distinct. You will avoid a lot of unwanted dependencies and mess this way. Having 2 copies of the same assembly on developer machines is perfectly fine and desirable.

    -Karel


    I understand the point you are making, but I can't agree with all you say.

    Your example about releasing an update is surely an example of DLL ____? and I thought that a) the GAC, b) singed assemblies and c) version specific dependencies was designed to eliminate that?

    If I add a new version of some assembly to a machine, then by defintion this can take advantage of side-by-side execution..

    Anyway, you miss the point.

    In Visual Studio, if I set a ref to some 3rd party assembly, then VS populates its .Net Tab (in the Add Reference dialog) from some arbitrary directory where a copy of my assemblies have been placed. Then later on, when I run my app it does load the assemblies from the GAC. (If I set copy local to OFF).

    So this is potentially more confusing not less.

    This is a Microsoft hack in my view, if my app is going to load an asembly from the GAC (which it will strive to do if copy local is off) then surely to avoid confusion, it should use the same assembly files to populate the Add Reference dialog.

    We dont need to combine the GAC with some reserved folder in order to handle some versioning scenarios, we just don't.

    In my view a developer should not need special support for any needs, Visual Studio, developers, working practices etc should all be dealt with by a consistent use of the GAC, read any software book: Data Duplication should be avoided at all costs.

    It is SharpDevelop that has got it right.

    Cap'n

    Monday, October 19, 2009 4:04 PM
  • > must install TWO copies

    Meditate on the meaning of "cache".  ;-)

    That said, there are numerous things about assembly loading, including the GAC, that I don't like.  Oh well, not much can be done about it...

    Yes, I don't expect MS to issue a service pack and address this, I'm not asking that.

    If you re-read my opening post, you will see that I was truly confused about this, it is totally bizzare to discover that Visual Studio can't see installed assemblies unless a copy is placed into some special folder AND the registry gets modified to include that special folder so that VS can see this special folder.

    Also (as some have mentioned) we don't need an API to "get the file path of GAC assemblies" and I was not asking for that (this suggestion sprouts from some people's ideas about solutions, it comes from the solution domain). What we do need is simple, very simple, Visual Studio be able to enumerate assemblies in the GAC, plain and simple.

    Now this is possible, SharpDevelop does it and this sheds light on it too.

    Let paraphrase what my perception:

    Me: High, I have coded my assemblies and now need to code my installer to put them in the GAC for apps and developers to use.
    MS: Sure, no probs, as you know the GAC eliminates DLL ____, you know, when we have mixed up version of stuff spread all over.
    Me: Yes, I heard that, this is great I'm excited to be able to build systems without this messy and confusing stuff getting in the way.
    MS: Good. Well all you do is edit your setup/install project and expand the GAC tree node, then drag your assemblies here, the setup will then do all you need.
    Me: Really? wow that's great, I was hoping it would be that neat, its greate to have this consistent and simple way of working.
    MS: Yes it is, we put a lot into this GAC stuff, now many apps can share a single, well defined, signed, versioned copy of an assembly, we can even have several different versions all installed side by side.
    Me: That's great, really is, but I have one question?
    MS: Yes, what is it?
    Me: I tested the setup, the stuff did indeed go into the GAC and all the installed apps also work and find the GAC assemblies, but...
    MS: Go on...
    Me: Well if I do an Add Reference in Visual Studio I cant seem to find my installed assemblies.
    MS: Oh erm, yes thats true you cant "see" installed GAC assemblies in Visual Studio.
    Me: Really?
    MS: Erm, yes, really, if you want Visual Studio to list an assembly in Add Reference then you must place the assembly in a folder of your choice, then modify the registry so that AssemblyFolders contains your folder and you must do this for either the user or machine.
    Me: Oh. You mean I must do something special for Visual Stduio? you mean Visual Studio has special needs, and can't leverage this simple GAC working model?
    MS: Yes, thats right, Visual Studio is the only app that requires your assemblies to be installed in TWO PLACES ON A MACHINE.

    In other words, this is clumsy and surprises almost everyone who encounters it.

    Cap'n









    Monday, October 19, 2009 4:27 PM
  • Your example about releasing an update is surely an example of DLL ____? and I thought that a) the GAC, b) singed assemblies and c) version specific dependencies was designed to eliminate that?

    If I add a new version of some assembly to a machine, then by defintion this can take advantage of side-by-side execution..
    I agree that your statement should be true for standalone applications (most of the managed code in the world). With frameworks the requirements are a little bit different and the model doesn't suite them that well, because:
    1. You want to push security fixes everywhere. You don't want to keep the old insecure version side-by-side for some random app to pick it up and run on it, because it would be potentially vulnerable.
    2. Service packs tend to contain more security fixes and also some bigger changes and improvements (incl. new APIs). Service packs for .NET Framework libraries (and many other Microsoft managed libraries) are updated in-place (without bumping assembly version). That potentially introduces new APIs.
    Monday, October 19, 2009 5:01 PM
    Moderator
  • Anyway, you miss the point.

    In Visual Studio, if I set a ref to some 3rd party assembly, then VS populates its .Net Tab (in the Add Reference dialog) from some arbitrary directory where a copy of my assemblies have been placed. Then later on, when I run my app it does load the assemblies from the GAC. (If I set copy local to OFF).

    So this is potentially more confusing not less.

    This is a Microsoft hack in my view, if my app is going to load an asembly from the GAC (which it will strive to do if copy local is off) then surely to avoid confusion, it should use the same assembly files to populate the Add Reference dialog.

    We dont need to combine the GAC with some reserved folder in order to handle some versioning scenarios, we just don't.

    In my view a developer should not need special support for any needs, Visual Studio, developers, working practices etc should all be dealt with by a consistent use of the GAC, read any software book: Data Duplication should be avoided at all costs.

    It is SharpDevelop that has got it right.

    Cap'n
    I don't think I miss the point. While I agreee that this is confusing, I think it is correct and this is exactly what should happen.
    Note that Visual Studio 2010 goes even further with this and uses reference assemblies concept. Reference assembly is yet another copy on disk of assembly you depend on (possibly with stripped off IL code as it is not needed). That is great concept for .NET Framework libraries, because you can in theory choose if you want to target RTM, SP1, or SP2 version of particular Framework/library and you will not get wrong IntelliSense for classes/methods which are not present in the version you are targetting.

    I agree that 99% of developers don't care about this. But one day, one of them will use a new API introduced in Fx 2.0 SP2. He will run it, test it on his machine and then hand it to the customer and boom! It doesn't work for the customer, because customer has only version Fx 2.0 SP1 and the API is not there. He will find out eventually what's going on and then will go to VS and fix it. (Let's assume his customer doesn't want to or cannot upgrade to Fx 2.0 SP2 - e.g. it is a bank which has strict policies on Fx version installed)
    But if there are only GAC assemblies in Add Reference dialog (as you propose), how can he do that? He could roll back to Fx 2.0 SP1 on his machine, but ... What about his other projects? What if some app he is using or VS itself depend on Fx 2.0 SP2? OK, so he will just stop using that API. But now there's a doubt in his mind: Is it gonna happen again in the future? How can I prevent it? Why did VS allow this at the first place?

    I hope this shows that this is not random data duplication we should avoid. It hopefully explains my point that there are 2 processes which are dinstinguish - building and running (deployment). It is IMO good that Visual Studio prevents developers from mixing them up. And having 2 (or 3 or 4) copies of the assembly on disk is IMO a small payment for the possible advantages.
    Maybe someone still thinks that it is stupid not showing GAC assemblies, but I think it is in general for our (developers') good.

    -Karel

    BTW: I don't want to start a flamewar. I don't claim I am 100% right (actually I might be wrong and missing some angle here). I tried to explain my (personal) view on this thing here and I respect that someone has different opinion. I'll welcome any feedback on what I wrote ...
    Monday, October 19, 2009 5:36 PM
    Moderator
  • Anyway, you miss the point.

    In Visual Studio, if I set a ref to some 3rd party assembly, then VS populates its .Net Tab (in the Add Reference dialog) from some arbitrary directory where a copy of my assemblies have been placed. Then later on, when I run my app it does load the assemblies from the GAC. (If I set copy local to OFF).

    So this is potentially more confusing not less.

    This is a Microsoft hack in my view, if my app is going to load an asembly from the GAC (which it will strive to do if copy local is off) then surely to avoid confusion, it should use the same assembly files to populate the Add Reference dialog.

    We dont need to combine the GAC with some reserved folder in order to handle some versioning scenarios, we just don't.

    In my view a developer should not need special support for any needs, Visual Studio, developers, working practices etc should all be dealt with by a consistent use of the GAC, read any software book: Data Duplication should be avoided at all costs.

    It is SharpDevelop that has got it right.

    Cap'n
    I don't think I miss the point. While I agreee that this is confusing, I think it is correct and this is exactly what should happen.
    Note that Visual Studio 2010 goes even further with this and uses reference assemblies concept. Reference assembly is yet another copy on disk of assembly you depend on (possibly with stripped off IL code as it is not needed). That is great concept for .NET Framework libraries, because you can in theory choose if you want to target RTM, SP1, or SP2 version of particular Framework/library and you will not get wrong IntelliSense for classes/methods which are not present in the version you are targetting.

    I agree that 99% of developers don't care about this. But one day, one of them will use a new API introduced in Fx 2.0 SP2. He will run it, test it on his machine and then hand it to the customer and boom! It doesn't work for the customer, because customer has only version Fx 2.0 SP1 and the API is not there. He will find out eventually what's going on and then will go to VS and fix it. (Let's assume his customer doesn't want to or cannot upgrade to Fx 2.0 SP2 - e.g. it is a bank which has strict policies on Fx version installed)
    But if there are only GAC assemblies in Add Reference dialog (as you propose), how can he do that? He could roll back to Fx 2.0 SP1 on his machine, but ... What about his other projects? What if some app he is using or VS itself depend on Fx 2.0 SP2? OK, so he will just stop using that API. But now there's a doubt in his mind: Is it gonna happen again in the future? How can I prevent it? Why did VS allow this at the first place?

    I hope this shows that this is not random data duplication we should avoid. It hopefully explains my point that there are 2 processes which are dinstinguish - building and running (deployment). It is IMO good that Visual Studio prevents developers from mixing them up. And having 2 (or 3 or 4) copies of the assembly on disk is IMO a small payment for the possible advantages.
    Maybe someone still thinks that it is stupid not showing GAC assemblies, but I think it is in general for our (developers') good.

    -Karel

    BTW: I don't want to start a flamewar. I don't claim I am 100% right (actually I might be wrong and missing some angle here). I tried to explain my (personal) view on this thing here and I respect that someone has different opinion. I'll welcome any feedback on what I wrote ...

    Thanks for the post, you do raise some interesting scenarios, I need to carefully read what you are saying here, you may well have a point. I do know that I was told over and over, in the early days of .Net, how the GAC and side-by-side deployment, strict version dependency enforcement and so on, spelt the end of DLL helll and complicated issues of multiple copies etc.

    The way Microsoft and many writers emphasized this may be to blame, nowehere did MS talk about this GAC and Add Reference issue (they do now) nor did excellent books like Juval Lowy's Programming .Net Components.

    No flame war wanted or intended, I just feel that MS should deliver on their promise, because not once do they say "Oh by the way, there is a situation in which all our new GAC stuff won't work, and that is Visual Studio itself".

    So far as I understood this, once you build a signed assembly against a specific signed version of some other assembly, then you are forced to run with that assembly, no other version will load, the runtime will insist that the version you built against be present or the app dies.

    I also wonder why the Add Reference dialog looks so weak, I mean the .Net tab, could have subtabs, one per vendord, like: System, Microsoft, IBM, Oracle and so on, or perhaps even make it a tree view, where it is portrayed as a hierarchy, rather than some long list as it is now, each vendors branch/tab could then have a per-version branch or tab, making more elegant and organised to select the correct assembly, this would make it dead easy to see SP1, SP2 or whatever versions.

    Now the case you cite "It doesn't work for the customer, because customer has only version Fx 2.0 SP1 and the API is not there. He will find out eventually what's going on and then will go to VS and fix it." doesnt make sense, because this is an issue between user and supplier, prerequisites and so on. In this case a vendor has released some code that requires SP2 yet he has failed to support customers who cannot install SP2. Besides, why would a customer not be able to install SP2? because of side-by-side support there should be no risk in doing this, because existing signed apps will never use the SP2 stuff because they have been built and signed to run with SP1, installing SP2 should never ever break existing apps; ins't this the whole point of signing?

    Now don't get me wrong I am not saying "But if there are only GAC assemblies in Add Reference dialog" I never said that. I did say that Visual Studio's .Net tab (in Add Reference dialog) should automatically list what is in the GAC, I have no proble, with Visual Studio having the other tabs and allowing other references, my main gripe is simply that I cannot place an assembly in the GAC and then see it in Visual Studio's Add Reference, I think this is poor design (but I may be missing something).

    Anyway, let me ponder your post....

    Thx

    Cap'n



    Monday, October 19, 2009 10:22 PM