[Mono-list] Assembly mutual dependencies or chicken-and-egg problem

Jaroslaw Kowalski jaak@zd.com.pl
Sat, 10 Jan 2004 00:38:15 +0100


Hi guys!

I'm implementing a Data Access Layer (with a source code generator) in C#
and I'm having a conceptual problem with partitioning my design into
assemblies as it involves mutual dependencies.

Maybe someone can give me some advice?

Problem statement (a bit long - sorry)

1. The system represents database entities as objects (O/R mapping)

2. All entities ultimately derive from some base class that provides common
functionality. Let's call it BaseObject.

3. On top of that there's a C# code (generated by some stub generation
utility) that creates a class for each database table. Class is named
"tablename_STUB" and derives from "BaseObject".

4. I'd like the user to be able to implement additional methods so I create
another class for each database table, called "tablename". The idea is that
this class will never be re-generated while "tablename_STUB" will be
regenerated whenever the database schema changes.

So basically I have:

class BaseObject {}
class SomeTable_Stub : BaseObject { }
class SomeTable : SomeTable_Stub { }

5. I want the instance of "SomeTable_Stub" to be able to return references
to "SomeTable" objects. This will be used to represent foreign key
relationships and I don't want to clutter SomeTable with any boilerplate
code. So this needs to be done in the Stub class and inherited.

Now I'd like to partition the system into separate assemblies:

BASE - which will contain BaseObject and helper stuff
STUBS - which will contain "_Stub" classes (regenerated after the schema
changes)
and
BUSINESS_OBJECTS - which contains classes without "_Stubs".

My problem is that there's a mutual dependency between STUBS and
BUSINESS_OBJECTS. So I'd need STUBS.dll referencing BUSINESS_OBJECTS.dll and
vice versa.

I don't know how to accomplish it best.

I've looked at mono makefiles and found that "System.dll" references
"System.Xml.dll" and "System.Xml.dll" references "System.dll". Somehow we
have a chicken-and-egg problem because it's not directly buildable.

I came up with the following idea to build this project:

1. Build BASE.dll
2. Create a small assembly that will have all the classes and methods that
STUBS.dll needs from BUSINESS_OBJECTS.dll but they derive from BaseObject
and the methods will be stubbed out.
3. Compile this fake assembly (referencing BASE.dll) and name it:
"BUSINESS_OBJECTS.dll"
4. Compile "STUBS.dll" passing it a reference to this fake
"BUSINESS_OBJECTS.dll"
5. Now that we have "STUBS.dll" we can recompile the actual
"BUSINESS_OBJECTS.dll" with it.

I compiled it and even made it work, but I'm not convinced that this is the
best idea.

Q1: Do you see any problems in the long run?
Q2: Do you have any better ideas?
Q3: I'd like to be able to use VB.NET or JScript.NET for
BUSINESS_OBJECTS.dll while STUBS.dll will remain C#. Do you this this is
doable?
Q4: I know there can be issues with strong-names, but I believe it should
work. Am I right?

Jarek

P.S. I know I can keep the stubs and business objects in a single assembly
(this is actually how I did this before) but want to evaluate the
possibility of separating stubs and keeping them pre-compiled. The stubgen
phase takes a considerable amount of time and the stubs are getting large
(over 1MB of source code for a large database) so the compilation takes
time.

P.S.2. I'm planning to release my O/R mapping software as open source after
I resolve those basic issues and make it work with mono.