locked
System.dll references System.Configuration.dll which references System.dll? RRS feed

  • Question

  • We are trying to create a tree which contains all of our assemblies and their references. We started writing a tool which uses the GetReferencedAssemblies, and found ourselves in a recursive loop, which was completely unexpected. We then took ILDASM and looked at the manifest for System.dll, which contains this:
    .assembly extern System.Configuration
    {
    .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
    .ver 2:0:0:0
    }

    We thought it a little odd that System.dll would reference System.Configuration, so we then ran ILDASM on System.Configuration and checked it's manifest and found:

    .assembly extern System
    {
    .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
    .ver 2:0:0:0
    }

    YOIKS! A circular reference.

    How is that possible? Are we using GetReferencedAssemblies incorrectly?
    As far as I can tell, you are not supposed to be able to have circular references in assemblies.

    Any ideas?

    Wednesday, October 28, 2009 9:57 PM

Answers

All replies

  • You can do this using the command line compiler, or even Visual Studio, but it's messy.

    The basic approach is that you compile the portion of System that doesn't reference System.Configuration.  You use that to compile System.Configuration.  Then you add the other info back into System, and recompile it.  You end up with 2 assemblies, compiled, that reference each other.

    I highly recommend avoiding this, though.  If you want more info, this was discussed in detail here.
    Reed Copsey, Jr. - http://reedcopsey.com
    Wednesday, October 28, 2009 10:26 PM
  • Hello

    JunFeng Zhang from Microsoft explains this in detail:

    http://blogs.msdn.com/junfeng/archive/2004/02/01/65751.aspx

    <extract>

    In .Net framework System.dll and System.Xml.dll reference each other. How is it possible?

    Circularly referenced assemblies are chicken-and-egg problem. The trick is how to break the dependency chain.

    Here is one way I find working.

    Step 1. Create assembly A, includes A only types. A references nothing. (Except framework assemblies).
    Step 2. Create assembly B, uses A's types, and includes B only interfaces. B now references A.
    Step 3. Re-write A, includes A only types, and uses types in B. Now A also references B.

    </extract>

    Please feel free to post here if you have any other questions or concerns.


    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Thursday, October 29, 2009 8:28 AM
  • I'm not trying to reproduce circular references, I was just surprised to see it. I didn't think you could have circular references between assemblies.
    Thursday, October 29, 2009 3:53 PM
  • I'm not trying to reproduce circular references, I was just surprised to see it. I didn't think you could have circular references between assemblies.

    The key word here is you.  As in "You aren't supposed to have circular dependencies".

    That says nothing for Microsoft.  There's a few of those.  :)
    Coding Light - Illuminated Ideas and Algorithms in Software
    Coding Light WikiLinkedInForumsBrowser
    • Marked as answer by bpeikes Friday, November 13, 2009 7:00 PM
    Thursday, October 29, 2009 3:56 PM
  • Hello bpeikes

    As JunFeng said in the comment section of his blog http://blogs.msdn.com/junfeng/archive/2004/02/01/65751.aspx:

    I did not suggest this. I just show how it can be done. In fact, personally I am against this practice. But regardless what you and I believe, someone would like to know how to do this.

    It's recommended to avoid circular references in your own application.

    If you have any other questions or concerns, please feel free to post here.
     
    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by bpeikes Friday, November 13, 2009 7:00 PM
    Monday, November 2, 2009 5:44 AM
  • I just curious as to why you would ever want to do this. What scenarios would require circular references in assemblies?

    Monday, November 2, 2009 3:34 PM
  • For example, you develop a component that is composed of two components. The two components are cross dependent, but you have to develop them in two different languages. In this situation, you would run into cross reference. Here is a real case in which one component must be programmed in J#, and the other in C#:
    http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-sdk/1626/Have-2-projects-that-need-to-reference-each-other

    Please feel free to tell me if you have any other questions.
    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, November 3, 2009 3:03 AM
  • Hello bpeikes

    How are you? If you have any other questions, please feel free to post here.
    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, November 6, 2009 6:15 AM
  • I'm still not sure why you would have to do this even with multiple languages. Basically you're saying that you need to do this when you can't figure out how to split up your assemblies, which should never happen.
    Friday, November 6, 2009 4:13 PM
  • Frankly, I don't feel like there is a good scenario for us, as developers using the framework, to do this.

    However, for the multiple languages scenario:

    Say, for example, you were implementing a double linked list.  You might (for some odd reason) want to implement the Node class and the IEnumerator<T> implementation in C#,  but the list (that uses the node) in VB.NET.  In this case, the implementation of IEnumerator<T> will need to have access to the list (to enumerate it), so the enumeration class needs a reference to teh list's assembly.  But the list needs to create the enumerator, so it needs access to the enumerator's assembly.  Since you're using 2 languages, you end up being forced into a scenario with a circular reference.

    Granted, this is a stretch - it's a lot easier to just pick one language and go with it instead of trying to work around the circular references, but maybe it'd give you some ideas as to why somebody, somewhere, might want to try this.


    Reed Copsey, Jr. - http://reedcopsey.com
    Friday, November 6, 2009 5:05 PM
  • Well that's only the case if you need to define the interfaces in different languages. Implementation of the interfaces is a whole separate matter. Given your example:
    AssemblyA has interface definition for IEnumerator<T> and INode and ILinkedList
    AssemblyB has Node class which implements Node
    AssemblyC has double linked list class

    C references A and B
    B references A
    A references nothing

    Tada! No circular references.

    Friday, November 6, 2009 7:57 PM
  • Hello

    Yes, the problem can be worked around by adding the third assembly that defines the interfaces. However, in many cases, designers do not intend to add the additional assemblies. See the above mentioned case:

    The root problem is that the C# code implements an interface in the J#
    code. To make this work I think I would end up having to have 5 DLLs
    (things are very intertwined in the interface dependencies).


    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, November 9, 2009 3:32 AM