tags:

views:

128

answers:

5

Hi,

I have:

  • Main Program Class - uses Library A
  • Library A - has partial classes which mix in methods from Library B
  • Library B - mix in methods & interfaces

So in Library B when I include a partial Node class which implements INode (defined in Library B) I suddenly get an error in my main class where it uses Node from Library A. The error tells me in the Main Class I have to have a using statement to Library B.

Any ideas?

EDIT - Except from code

    // *** PROGRAM ***
    class Program
    {
        static void Main(string[] args)
        {
            var context = new Model1Container();
            Node myNode;  // ** WITHOUT A using for Library B I have an error here ***
         }
     }


// ** LIBRARY A
namespace TopologyDAL
{
    public partial class Node
    {
        // Auto generated from EF
    }

    public partial class Node : INode<int>   // to add extension methods from Library B
    {
        public int Key
    }
}

// ** LIBRARY B
namespace ToplogyLibrary
{
    public static class NodeExtns
    {
        public static void FromNodeMixin<T>(this INode<T> node) {
           // XXXX
        }
    }
    public interface INode<T> 
    {
        // Properties
        T Key { get; }

        // Methods
    }

}

EDIT 2 - To clarify was it a reference or using error:

So the error that appears against the "Node myNode;" line is:

Error 1 The type 'Topology.INode`1' is defined in an assembly that is not referenced. You must add a reference to assembly 'Topology, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. U:\My Dropbox\source\ToplogyLibrary\TopologyDAL_ConsoleTest\Program.cs 11 13 TopologyDAL_ConsoleTest

When I let VS fix it for me it adds the Library2 as a reference. That is there is no "using " either before or after in the client code. So the issue is a Reference not Using issue.

EDIT 3 - Not specifically about the question, however I now notice that in the program project, I can't see the mixin methods (from Library B) unless I have a using statement to Library B? I might create a separate question re this.

+5  A: 

If LibraryA exposes properties, returns objects from methods, or take parameters of types that are defined in LibraryB, and you declare or use a variable in Main Program of one of those types, you'll need the using statement.

Jay
I've added the code to give the example
Greg
@Greg As others have stated, you must add a *reference* to LibraryB no matter what. You haven't responded to others' questions whether you are actually being told that you need the `using` statement or a reference.
Jay
sorry - added an EDIT 2 clarification
Greg
@Greg Okay, problem solved. With respect to Edit3, that is how c# works. The `using` statement just brings the namespace into usable "scope." If you don't want `using` you can specify the full namespace declaration whenever you use types declared in LibraryB.
Jay
ok thanks too Jay
Greg
A: 

A partial class in c# is just a class that exists in multiple files. You cannot have 2 files that define a partial class in different namespaces.

Ben Robinson
+1  A: 

Since Library A is using mix in method and interfaces from Library B, a using statement is required if Library A and Library B exist in different namespaces, this is just how C# works. The compiler needs to know where to find the Library B types that are used in Library A.

Jeff Schumacher
+4  A: 

My understanding of what's happening is that you only reference Library A from Main program and compiler tells you to add reference to Library B because some types that Library A exposes are defined in Library B.

To fix this add a reference to Library B to Main program project.

Here is little diagram. If Library A exposes a type defined in Library B then Main must reference Library B as well. The below situation will not work:

_____________             _____________               _____________
| Main       |references  | Library A  |references    | Library B  |
|           -|------------|->         -|--------------|->          |
|            |            | public     |              | SomeType   |
|            |            |  SomeType  |              |            |
|            |            |            |              |            |
-------------             -------------               -------------

This is only an issue when a type defined in Library B is accessible through Library A. This will be in one of the following situations:

  • EDITED Type defined in Library A (Node) derives from a type in Library B(INode<int>).
  • Method defined in Library A uses a type from Library B as return type or as an argument.
  • Type defined in Library A exposes a type from Library B as a property or a public field.

You will need to add a reference to Assembly3 from Assembly1 to make it compile.

_____________             _____________               _____________
| Main       |references  | Library A  |references    | Library B  |
|           -|------------|->         -|--------------|->          |
|            |            | public     |              | SomeType   |
|            |references  |  SomeType  |              |            |
|           -|------------|------------|--------------|->          |
|            |            |            |              |            |
-------------             -------------               -------------
Igor Zevaka
thanks Igor - I've added the code to give the example - in this case all I'm doing is using "Node", which is actually defined in Library A though?
Greg
I've updated the post. Yes, you need to add reference to lib A as it comes under Rule 1 - Lib A defines a type that inherits a type from lib B.
Igor Zevaka
sorry - added an EDIT 2 clarification
Greg
saw you modification - is it me or does it seem a little silly that we have to manually add a reference in the main project? Is there not a way to tell LibraryA to always bundle it's dependencies perhaps?
Greg
Nope. That's pretty fundamental to how .net project references work.
Igor Zevaka
ok thanks Igor.
Greg
A: 

All you're using is the Node class from Library A, that's true. However, part of the definition of the Node class is the fact that it implements the INode<int> interface from Library B.

The very fact of the existence of the Node class demands that you include a reference to Library B.

John Saunders