2 Projects Sharing 1 Set of Files

G

Guest

I'm building a solution that has 1 component for the Desktop and 1 component
for the Pocket PC. (Though this isn't a mobile question).

I have a data library that will be shared on both platforms. So I've
adopted the approach of having two projects share the same set of files. In
my case, I have two similarly named projects:
DataObjects
DataObjectsCF

The former is for the Desktop app and the latter is for the Compact Framework.

Throughout the many classes shared by these two projects I have some
conditional compilation statements that look like this:
#if (CF)

where 'CF' is used to denote code only for the Pocket PC and conversely
'!CF' is for code only for the Desktop.

I opened up the properties of DataObjectsCF and added the conditional
compilation constant 'CF'. Strangely though, this treated all the files
"looked at" by DataObjects as if I were debugging the Pocket PC app, when
clearly I was working with the Desktop app.

Why is this?
 
T

Tim Wilson

There is an issue (at least I classify it as such) where if you have two
projects, in the same solution, that are linking to the same file, then when
that file is open the last project that was loaded into the solution will
take precedence over the others and the conditional constants for this
project will be honored as well as intellisense showing information based on
the references of the last project loaded. In short, if you're sharing files
between projects in the same solution, and one project is targeting the full
framework while the other is targeting the compact framework then you may
see issues, as it appears is the case in this situation. The only workaround
that I'm aware of is to place each project into its own solution. It's not
nice but it's better than dealing with the phantom issues of shared files.
The other option in your situation is to code, and compile, your class
library against the compact framework, using only compact framework classes
that also exist in the full framework, and the class library will be usable
on the desktop as it is retargetable.
 
G

Guest

Tim,

Thank you for your response. I think you've hit the nail on the head
because so-called "phantom issues" seem to be exactly what I'm experiencing
now. They're scary!

With regard to your latter idea, if I were just to code everything for the
CF then I would manually copy the resultant DLL into the WinForms project?
Put another way, how do I force a class library to always compile for the CF?
 
T

Tim Wilson

With regard to your latter idea, if I were just to code everything for the
CF then I would manually copy the resultant DLL into the WinForms project?
You would just add the class lib assembly (dll) as a reference and use it as
normal.
Put another way, how do I force a class library to always compile for the
CF?
Place the code to compile in a smart device project. The project would be
set up to compile against the CF.
 
G

Guest

Tim,

Sorry to be so dense about this (and Daniel Moth went to great pains to
explain it to me) but I do have another question.

I've removed the extra parallel projects so things were as before. Now ...
one of my top-level projects is called "Pocket PC". My other top-level
project is called "Desktop". Both reference my class libraries,
"DataObjects" and "Multimedia".

In the Pocket PC project I set a compiler constant called "CF". Then in
several places within the two class libraries I have #if (CF), #else, and
#endif statements.

My confusion is this: When I rebuild the Pocket PC project I had *thought*
that it would force the two DLLs to be built as if they were CF DLLs,
recognizing the 'CF' compiler constant. But after rebuilding I've checked
the file sizes and they're identical to when I rebuild the Desktop project.
So the CF constant is obviously not being recognized.

Or is it the case that I have to manually add the CF flag into each DLL's
properties each time before I rebuild Pocket PC? That's possible, of course,
but will be such a nuisance.

Hoping I explained my dilemma well.
 
T

Tim Wilson

Are you sure that you're still not running into the same issue? Try breaking
all the projects out into there own solutions and build the "common"
assemblies against the CF. So ensure that any class libs that you want to
consume from both the desktop and the device side are built from within a
smart device class library project. Just by building from within a smart
device project you will be targeting the CF. If you have any shared source
files then I'm assuming that this is where you have the #if...#else blocks,
and within a smart device project that contains one of these shared source
files you are defining the CF constant in the project properties. Then you
can add these assemblies as a reference to either a desktop or smart device
project.
 
G

Guest

Tim,

I just did as you said. I created a new solution, copied the required CF
related project folder underneath it (Pocket PC, DataObjects, and Multimedia
projects), and then added these projects into the solution. I rebuilt
everything.

Still, I got the same error as before:


An unhandled exception of type 'System.TypeLoadException' occurred in PP.exe

Additional information: Could not load type System.Drawing.Image from
assembly System.Drawing, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=B03F5F7F11D50A3A.


Maybe my interpretation is incorrect, but I assume this means that the
Multimedia project is STILL being compiled as an X86 WinForms one.

For this project I've pretty much given up on sharing DLL code. The only
fullproof method I've found is to build parallel, often identical, code
within the actual PocketPC project. That obviously compiles as CF-compliant
code whereas *I* can't seem to get it to do so if it's in a DLL ... even if
it's a CF-only solution as you've just instructed me to do.

Frustrating!
 
M

Mark Nijhof

Just out of curiosity (and to learn)

Why not create 3 common classes, one for shared code, one for the CF and
one for the normal framework?

-Mark
 
G

Guest

Mark,

I'm certainly not the expert here, but when I looked at this, I discovered
so many required cross references that I didn't know if it would work
correctly. But maybe somebody else on here might have some more experienced
views on your question.
 
T

Tim Wilson

Let me try to get my head around what you're doing a little better. You have
two class library projects that each output a dll (assembly) - DataObjects
and Multimedia - correct? You need to use both of these dlls on the desktop
and on a device, correct? I assume that both of these projects are smart
device projects? Do you have any code that is shared between these projects?
 
G

Guest

Tim,

By asking me whether "both projects are smart device projects", which 2
projects are you referring to? "Pocket PC" is definitely a smart device
project but "Desktop" is a WinForms project.

There is no code shared between "DataObjects" and "Multimedia".

By end goal/hope here is to find a simple (and safe) way to be able to use
each of DataObjects and Multimedia within each of Desktop and Pocket PC.
Currently I can use some of the methods in each but things fail on the Pocket
PC if I try to use things like Images and DataSets.
 
T

Tim Wilson

Ok. So let's go back and talk about the options. You have two ways to
approach this. In both situations you may want to think about how these
projects relate to each other. A solution is intended to group related
projects together. I assume by the fact that you stated that the DataObjects
project and the Multimedia project are not sharing code that these projects
are not really related. So you may consider placing each of the projects
into a separate solution - so that the DataObjects project is in one
solution by itself and the Multimedia project is in another solution by
itself. Then, to ensure that you don't run into any phantom issues you may
also want to place the Pocket PC project into it's own solution and Desktop
project into it's own solution as well. In total you would have four
projects and four solutions. This doesn't sound ideal but it could save you
some more frustration down the road. Now lets get to the options...

(1) You could build the DataObjects project and Multimedia project as smart
device class library projects. This would ensure that the resulting dll is
compiled against the CF. And, assuming that you're not using anything device
specific like the InputPanel component, then these assemblies will also be
usable on the desktop. One issue that you may run into, however, is that VS
may attempt to automatically pull in references when you add these
assemblies to the Desktop project. But I'm just going off of memory here. If
VS doesn't cause issues when adding a reference to the assemblies in your
Desktop project then this is the way that I'd go as it seems more logical to
share assemblies rather than share, or copy, code.

(2) You can create two project for each class lib. One for the desktop and
one for the device. So, and again understanding the phantom issues, you
would create a solution for the desktop DataObjects project and a solution
for the desktop Multimedia project and you would also create a solution for
the device DataObjects project and another solution for the device
Multimedia project. That's a lot of solutions, but what you could do is then
link the code into the projects between the desktop and device versions.
This may have been what you were doing before. At this point you would
differentiate any device and desktop specific code with conditional
compilation, defining the conditional compilation constants (or symbols) in
the appropriate project. This way would ensure that you are seeing proper
syntax highlighting as well as intellisense. Then you would add the correct
assembly (device or desktop) to the appropriate project (Pocket PC or
Desktop). This option gives you flexibility to add extra functionality that
is dependent on the full framework but yet share the bulk of the code
between the desktop and the device.

I guess it's up to you which one you choose, but if you don't need to do
anything specific to either the desktop or the device then I would attempt
the first option. If you do get jerked around by VS (which from memory is a
possibility when you attempt to add the assembly built against the CF as a
reference to the Desktop project) then the second option becomes the last
resort.

--
Tim Wilson
..NET Compact Framework MVP

Robert W. said:
Tim,

By asking me whether "both projects are smart device projects", which 2
projects are you referring to? "Pocket PC" is definitely a smart device
project but "Desktop" is a WinForms project.

There is no code shared between "DataObjects" and "Multimedia".

By end goal/hope here is to find a simple (and safe) way to be able to use
each of DataObjects and Multimedia within each of Desktop and Pocket PC.
Currently I can use some of the methods in each but things fail on the Pocket
PC if I try to use things like Images and DataSets.
 
G

Guest

Tim,

Thanks for your patience with me on this, I do appreciate it. The next time
you're in Vancouver, please give me a shout and I'll give you a great tour of
what was just ranked as the #1 city in the world. Anyhow ...

You've given me lots of food for thought. But I need to ask you something
about Option #1. You said, "You could build the DataObjects project and
Multimedia project as smart device class library projects." I think I must
be missing something because I just double-checked and these are the options
I have available to me in Visual Studio 2003:

Windows Application
Class Library
Windows Control Library
Smart Device Application
OpenNETCF Application
Etc.

But there is no "Smart Device Class Library" project option available. Is
there perhaps some "trick" I need to know about, such as creating a "Smart
Device Application" and then removing the default form, thus leaving me with
the equivalent of a class library?

Most curious,
 
T

Tim Wilson

In VS.NET 2003 the smart device wasn't quite as much of a first class
citizen as it is in VS 2005. You should select the "Smart Device
Application" project template. Once you proceed to create the project,
another dialog will appear asking which platform you want to target and with
what project type. It is at this point that you select "Pocket PC" in the
first listbox and then select "Class Library" in the second listbox.

--
Tim Wilson
..NET Compact Framework MVP

Robert W. said:
Tim,

Thanks for your patience with me on this, I do appreciate it. The next time
you're in Vancouver, please give me a shout and I'll give you a great tour of
what was just ranked as the #1 city in the world. Anyhow ...

You've given me lots of food for thought. But I need to ask you something
about Option #1. You said, "You could build the DataObjects project and
Multimedia project as smart device class library projects." I think I must
be missing something because I just double-checked and these are the options
I have available to me in Visual Studio 2003:

Windows Application
Class Library
Windows Control Library
Smart Device Application
OpenNETCF Application
Etc.

But there is no "Smart Device Class Library" project option available. Is
there perhaps some "trick" I need to know about, such as creating a "Smart
Device Application" and then removing the default form, thus leaving me with
the equivalent of a class library?

Most curious,
 
G

Guest

Tim,

Just to let you know ... I've now gone back and replaced my Multimedia.dll
with a Smart Device Class Library of the same name. And lo and behold
everything works ... including much original code that I had written that
"mysteriously" didn't work when I moved it from my CF project into the DLL.
Now it's no longer a mystery why!

I also just tested using this new & improved DLL in my Desktop project. It
seems to work fine. Later this week I'm going to start porting DataObjects,
which is much bigger, over to CF compliant code as well. I'll be most
interested to see whether it works okay with DataSets.

I'm just kicking myself that not until now did I know about Smart Device
Class Libraries. I should have investigated that further way back when.

I do have a lingering question for you: Is there ANY downside to my Desktop
app using the CF DLL? I mean, I realize that I'll have to write some special
code to compensate for missing features like SortedList, for example, but
having one set of source code rather than two copies of the same thing (which
rarely remain identical over time) is worth it for me. But are there any
other downsides that you can think of?
 
T

Tim Wilson

I do have a lingering question for you: Is there ANY downside to my
Desktop
app using the CF DLL? I mean, I realize that I'll have to write some special
code to compensate for missing features like SortedList, for example, but
having one set of source code rather than two copies of the same thing (which
rarely remain identical over time) is worth it for me. But are there any
other downsides that you can think of?
Other than what you stated about needed to reconstruct missing features in
the CF, I can't really think of a downside. It should just work. And if
you're ok with limiting yourself to CF-only types and members than it may be
easier to just deal with this one dll, rather than one for the desktop and
one for the device.
 

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