Probably an easy question re: Namespaces

M

Mitchell Freeman

I am having a problem accessing/sharing classes/objects between projects
contained within a single solution. I was under the impression that
namespaces was the answer I was looking for, but it seems I am not getting
anywhere with it and I hope I can get a little help. I've browsed the
on-line docs and the MSKB as much as I can, but I cannot seem to get what I
think should work to actually work. I am using VS.net 2003 Enterprise
Edition, and am working in C# exclusively at this point.

This is a rough pseudo-code representation of what I have:

Solution "A"
Project "B"
namespace X
public class1
public class2
public class3
Project "C"
using X; (tried both with and without this line, no difference.)
namespace X (I want all these to be in the same namespace if
possible, but they don't HAVE to be)
public class4
...
class1 ObjName1 = new class1(); // I want to use the class1
classes defined in
class2 ObjName2 = new class2(); // project B here in project
C.
...

The problem occurs when I compile Project C. I get an error on both of the
lines above (in class4) that tells me "The type or namespace name 'class1'
does not exist in the class or namespace 'RESTS' (are you missing an
assembly reference?)". I get the same error for class2 (no big shock there).
I have tried coding the lines like "X.class1 ObjName1 = new X.class1();" and
I have tried doing different namespaces between the projects (X and Y), but
none of those seemed to either work or even give me anything other than the
same error message. I have also looked for a global solution-wide NAMESPACE
field in the project/solution properties, as well as where to add something
to either of the projects to make it seen by the others. Even according to
the on-line documentation about

I have to imagine that what I am attempting to do is not impossible (or is
it) and that I am just missing some significant yet small and simple step to
make it work. What lunacy am I self-inflicting on my solution? Could someone
please point me in the right direction? It would be most appreciated.
 
G

Gabriel Magana

You need to add a reference on project "C" to project "B"... Right click on
project "C"'s references folder, add a "project reference" to project "B".
 
B

Bruce Wood

I've never tried using the same namespace in multiple assemblies. Since
the assembly name forms part of the (true) name of each type defined in
an assembly, I would assume that using the same namespace in two
assemblies would just create a big mess, but I could be wrong.

That said, your

using X;

should have worked, so long as project C has a reference to project B's
DLL in its "References" section. By the way, project B _is_ a DLL,
isn't it? If it's an executable then you can't do that in Windows: EXEs
can reference types in DLLs, and DLLs can reference types in other
DLLs, but you can't "use" types compiled into an executable from other
assemblies.

I'm not sure whether you have to manually add a reference to a DLL
within the same solution, but you can check by going to the Solution
Explorer and expanding the References list for Project C. If you don't
see Project B in there, then you need to right-click the words
References under Project C and "Add Reference..." You want to choose
the Projects tab and pick Project B's DLL. Then all should be happy.
 
M

Mitchell Freeman

Thanks to both of you, Gabriel and Bruce.

I did find that "Add a reference" and tried that, but I ran into the very
problem Bruce detailed below--that being Project B is not a .DLL, nor do I
think I want it to be. But that may be the crux of the problem: Maybe my
idea/understanding of a "solution" and "projects" is not what Microsoft had
in mind and I am making this harder on myself than I need to.

Without getting into the whats, whys, and wheretofores, what I am attempting
to do is create a "core program" that will also have several standalone
utilities that go with it. Project B is the first standalone utility--a
Windows application (as opposed to a command-prompt-based app) that connects
to a DB server and automatically creates all the tables, views, etc. that
the rest of the core and other standalone utility programs will need.
Project C is a Windows application as well. More importantly it is the entry
point for the "core program", and I expect most of the code in this project
to be here.

Then we have the previously-unmentioned "Project D" which will be yet
another standalone utility, as will E, F, and G. To be clear, Projects B, D,
E, etc. will be things that people would need to run when NOT using the core
program (Project C). The standalone utilities are either "preparation
functions" or "maintenance/security" functions that need to be separate from
the main program. While they may share a few objects in common (B is the
first app to need class1, but C needs to use class1, as well as D and
others, potentially), I view them as separate programs, and therefore
separate projects.

Is my original problem one of a poorly/incorrectly structured
"solution/project"? What is the "correct" (and by that, I mean
Microsoft-intended, not to say that they're always correct) way of setting
up this structure? The numerous books I've read on the topic tall all day
long about tiers, separating business logic from general application
functionality, etc., but I have yet to see one that talks (in any kind of
meaningful detail) about structuring your project in terms of strategies of
using Solutions versus Projects or both or neither or ??.
 
G

Gabriel Magaña

I doubt you can escape external DLLs if you want to share code... .NET is
just not the right thing to use to create single .exe applications, there
are always references to something else.

Why not just create an assembly (dll) with the shared code, and then you can
make as many EXE files reference that assembly? That would be much
cleaner...
 
B

Bruce Wood

Your problem really doesn't have to do with layer, which are an
architectural concern. Yours is really more a practical problem of
building your code into deployable modules.

You need to put the core bits of your code, the classes that will be
used by more than one program, into a separate project and build it as
a DLL, not an executable.

Then your main program and each of the utilities will reference that
DLL. So far as I know, that's the way MS has always done it: any given
loadable module is either a library (DLL) or an executable program
(EXE). Executable programs and libraries can reference things in other
libraries, but an executable is a closed box that nobody else can see
inside.

"Solutions" were something added by Visual Studio / .NET. In your case,
I would put all of your projects to produce all of those executables
under one "solution," as they all appear related to solving different
aspects of the same problem. I see "solutions" as more transient
things, though. It's the "project" that really matters: these source
files produce this assembly. How I choose to work with those at any
point in time (the "solution") is more changeable.
 
J

Jon Skeet [C# MVP]

Bruce Wood said:
Your problem really doesn't have to do with layer, which are an
architectural concern. Yours is really more a practical problem of
building your code into deployable modules.

You need to put the core bits of your code, the classes that will be
used by more than one program, into a separate project and build it as
a DLL, not an executable.

Then your main program and each of the utilities will reference that
DLL. So far as I know, that's the way MS has always done it: any given
loadable module is either a library (DLL) or an executable program
(EXE). Executable programs and libraries can reference things in other
libraries, but an executable is a closed box that nobody else can see
inside.

This is actually a VS limitation rather than a .NET limitation. .NET
itself doesn't stop a DLL from referencing an executable, and nor does
the C# compiler. In fact, you can edit the project file yourself to add
a reference:
 
J

Jon Skeet [C# MVP]

[Sorry - posted it half way through writing it]
This is actually a VS limitation rather than a .NET limitation. .NET
itself doesn't stop a DLL from referencing an executable, and nor does
the C# compiler. In fact, you can edit the project file yourself to add
a reference:

(In VS.NET 2003, I believe - I haven't tried it myself, nor have I
tried in VS 2005.)

<Reference
Name = "IPlugin"
AssemblyName = "PlugInTest"
HintPath = "..\PlugInTest\bin\debug\plugintest.exe"
/>

It would be better to turn it into a class library though.
 
M

Mitchell Freeman

Considering how VC likes to manhandle the code files (writing over whatever
it thinks is supposed to be a certain way), wouldn't making this kind of
change also be overwritten the next time I had VS run my build or add a new
project or change the solution in some way?

In either case, it sounds like breaking out the shared classes/objects into
a separate DLL is probably the better/smarter idea. Probably should have
thought of that in the first place.

This of course begs the question: what is the correct and/or effective use
of namespaces if what I am (was) attempting to do is not possible with them?
Having taught Java for a number of years, I certainly understand packages
and hierarchies and the value/meaning/impact they have to a project. But if
Namespaces don't provide/allow you the same flexibility, what's the point?

The reason I ask: I can certainly see myself creating a namespace/package
hierarchy of my own with the various shared classes I'll need to create. For
example: mysystem, mysystem.maintenance, mysystem.security, etc. How do
projects and/or solutions impact the design/location necessities of my
classes in the various code files, or do they all need to be lumped together
one file per namespace?

Jon Skeet said:
[Sorry - posted it half way through writing it]
This is actually a VS limitation rather than a .NET limitation. .NET
itself doesn't stop a DLL from referencing an executable, and nor does
the C# compiler. In fact, you can edit the project file yourself to add
a reference:

(In VS.NET 2003, I believe - I haven't tried it myself, nor have I
tried in VS 2005.)

<Reference
Name = "IPlugin"
AssemblyName = "PlugInTest"
HintPath = "..\PlugInTest\bin\debug\plugintest.exe"
/>

It would be better to turn it into a class library though.
 
J

Jon Skeet [C# MVP]

This of course begs the question: what is the correct and/or effective use
of namespaces if what I am (was) attempting to do is not possible with them?
Having taught Java for a number of years, I certainly understand packages
and hierarchies and the value/meaning/impact they have to a project. But if
Namespaces don't provide/allow you the same flexibility, what's the point?

They do allow you the same flexibility.
The reason I ask: I can certainly see myself creating a namespace/package
hierarchy of my own with the various shared classes I'll need to create. For
example: mysystem, mysystem.maintenance, mysystem.security, etc. How do
projects and/or solutions impact the design/location necessities of my
classes in the various code files, or do they all need to be lumped together
one file per namespace?

No, you don't need to use one file per namespace. However, you need to
be very clear in your own mind about where namespaces apply and where
assemblies apply. A lot of people get this mixed up, partly due to them
often being the same (i.e. someone putting namespace Foo.Bar in
assembly Foo.Bar.dll.)

You can have multiple assemblies contributing to a single namespace,
and multiple namespaces in a single assembly. Just like Java and jar
files, really (except that assemblies are first class citizens in .NET
rather than just incidental details of class loading).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top