[Gtk-sharp-list] [PROPOSAL] Eliminating Application.Init ()

Jonathan Pryor jonpryor@vt.edu
Sun, 14 Sep 2003 20:53:53 -0400


I'm failing to see, immediately, how the Singleton pattern would work. 
Singleton just permits access to a single, well-known, instance of a
particular type.

Fortunately, after talking with a friend about this issue, I'm willing
to stand corrected. :-)

Implicit initialization is nice, when you can ensure that it won't screw
things up.  I was previously convinced that the ordering issues would be
difficult to solve.

To the contrary, it's fairly easy: have libraries invoke the
initialization code of libraries they're dependent upon.  Thus, if
Library2 is created before Library1, it's OK, since the Library2
initialization code would implicitly invoke Library1's code.  For
example:

	class Lib1.Foo {
		static Foo () { /* code ... */ }
		public static bool initialized;
	}

	// Lib2.Bar is dependent on Lib1.Foo
	class Lib2.Bar {
		static Bar () {
			// implicitly calls Lib1.Foo::.cctor, which
			// initializes Lib1.
			bool ignored = Lib1.Foo.initialized;

			/* other initialization code... */
		}

		// so other libraries can do the same thing
		public static bool initialized;
	}

Static variables don't need to be used; static functions/properties
could be used instead.  The key point is that the libraries know what
their dependencies are, so when a user creates a type anywhere in
dependency list, all dependencies will be initialized *in order*.

Wish I'd thought of this before.  It's rather useful.

There is a downside with this in Gtk#, though.  AppDomains.

Static class constructors are invoked once per AppDomain (assuming that
any instance of the type is created).  This means that GTK+
initialization code would be invoked 1 x (# AppDomains using Gtk#).  If
this is > 1, you might abort the process as some of the GLib
initialization code can only be called *once* per process.  (IIRC, this
was related to threading, is very annoying to work around, and is in
bugzilla against the offending library.  I don't think this has been
fixed yet, though.)

 - Jon

On Sat, 2003-09-13 at 23:15, Michael Poole wrote:
> Jonathan Pryor <jonpryor@vt.edu> writes:
> 
> > So, you want to rely on the Library to handle initialization order?
> >
> > Sorry for being bold and/or mean, but are you insane?
> >
> > The problem is that static constructors guarantee NO ORDER.  The only
> > thing you can assume is that the static constructor will be invoked
> > before any static members are accessed, or any types are created.
> >
> > You can't say "this .cctor should execute before this other .cctor
> > (which could be located in a completely different assembly!)."
> 
> You cannot specify cross-assembly ordering of .cctors, but you can
> adapt the Singleton pattern to ensure correct ordering.  Implementing
> that as a CLI Attribute-type class is left as an exercise for the
> reader.  It does add a line or two of code to the library's
> implementation, but it saves that much code from every application.
> 
> The significant difference between this and the apartment models is
> that the Init()-type functions take no arguments, but more than one
> threading model is possible.  As you pointed out later in your email,
> automatic initialization is appropriate only for cases where the
> argument list is trivial.
> 
> Michael
> _______________________________________________
> Gtk-sharp-list maillist  -  Gtk-sharp-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/gtk-sharp-list