[Mono-list] Assembly mutual dependencies or chicken-and-eggproblem

Jaroslaw Kowalski jaak@zd.com.pl
Mon, 12 Jan 2004 14:10:18 +0100


Thanks for your answer.

Actually I've developed a foolproof version of the build process:

1. I have a script that creates a "mini" version of business.dll containing
nothing but all classes and their constructors. The classes inherit from
their _Stub counterparts.

2. I have another script that creates a "mini" version of "stubs.dll"
containing nothing but all "*_Stub" classes and their constructors. The
classes inherit "BaseObject".

3. The compilation process is:

a) compile "mini" stubs.dll (references nothing but base.dll)

b) compile "mini" business.dll (references "mini" stubs.dll - this must use
the same version and keyfile, to take care of strong names)

c) compile full stubs.dll (references "mini" business.dll)

d) full "business.dll" can be recompiled now against full stubs.dll.

This may cause warnings (or even errors) with compilers that complain that
"business.dll" is not found when compiling "business.dll" (in step "d"), but
can be easily overcome with:

csc /out:business.dll /r:path_to\stubs.dll /r:\path_to\mini_business.dll
business*.cs

Actually csc produces only a warning so I need to reference only
"stubs.dll".

DO YOU SEE ANY POTENTIAL PROBLEMS WITH THIS AND MCS?

Jarek
----- Original Message ----- 
From: "Jonathan Pryor" <jonpryor@vt.edu>
To: "Jaroslaw Kowalski" <jaak@zd.com.pl>
Cc: "Mono List" <mono-list@ximian.com>
Sent: Monday, January 12, 2004 1:52 PM
Subject: Re: [Mono-list] Assembly mutual dependencies or
chicken-and-eggproblem


> You note that System.dll and System.Xml.dll are mutually dependent.
> They are built, however, by referring to the previous versions of the
> assemblies.  So System.dll "version" (build?) 101 is built against
> System.Xml.dll build 100 (previous build), and System.Xml.dll (which is
> built after System.dll) can depend System.dll build 101 (current).
>
> It doesn't look like this will easily work for your scenario.
>
> The simple thing to do would likely be to break the dependency, and have
> the Stub objects just refer to the other Stub objects.  The non-stub
> objects can then expose new methods/properties, offering the
> properly-cast stub objects for consumption.
>
> Pro: No mutual dependencies between assemblies; if the user stays within
> the "tablename" classes, they'll never see the Stub classes.
>
> Con: Requires that the user-editable classes have boilerplate code (the
> method/property overrides that expose the correct type).
>
> Example:
>
> // Assembly: Base.dll
> class BaseObject {}
>
> // Assembly: Stubs.dll
> class Table1_Stub : BaseObject {
> public Table2_Stub Table2 { get; set; }
> // ...
> }
>
> // Assembly: Business.dll
> class Table1 : Table1_Stub {
> public new Table2 Table2 {
> get {return (Table2) base.Table2;}
> set {base.Table2 = value;}
> }
> // ...
> }
>
> If the boilerplate code is an issue (and it could be, with enough table
> values), introducing a "_Impl" class might work.  It would have to be in
> the same assembly as the "tablename" classes, but I would think this
> would work:
>
> // Both of these in "Business.dll"
> // You could probably use CodeDom to generate the _Impl classes,
> // since it needs to be in the same language as Table1.
> class Table1_Impl : Table1_Stub {
> public new Table2 Table2 {
> // same as Table1, above
> }
> }
>
> class Table1 : Table1_Impl {}
>
> To answer your questions:
>
> > Q1: Do you see any problems in the long run? [with original approach]
>
> It's a complicated build process, and if the API exposed by the classes
> ever radically changes (new DB schema, etc.) I think you'd have to start
> the build "from scratch" (new stub classes, etc.).
>
> > Q2: Do you have any better ideas?
>
> See above.
>
> > 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?
>
> Yes.  The "barrier" between languages is the .netmodule or the
> Assembly.  Since each .dll is a different assembly, it should be fairly
> straightforward to use different languages in this manner.
>
> > Q4: I know there can be issues with strong-names, but I believe it
> should work. Am I right?
>
> I would think so, but I'm not the strong-name expert.
>
>  - Jon
>
> On Fri, 2004-01-09 at 18:38, Jaroslaw Kowalski wrote:
> > 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.
> >
> > _______________________________________________
> > Mono-list maillist  -  Mono-list@lists.ximian.com
> > http://lists.ximian.com/mailman/listinfo/mono-list
>