Fine control over type instantiation

  • Thread starter Thread starter Ben Blair
  • Start date Start date
B

Ben Blair

Hi All,

I'm looking for a way to cause type instantiation to call
a custom class factory instead of having the CLR create an
instance of the type on its own. Specifically, I need to
return a subclass instance when a new base class instance
is requested.

A simple class factory pattern would seem to work, except
that I need this to work with existing code that uses
the 'new' operator. I've got a library that can
automatically generate subclasses of existing classes but
with embedded monitoring code (and some other features).
Ideally, an existing application could use this simply by
making a small change in their runtime environment.
Requiring minor code changes in the application, such as
registering some event handlers on startup would be
acceptable. Requiring a user to replace all
MyClass a = new MyClass();
with
MyClass a = AClassFactory.CreateInstance();
is not acceptable. Not only would that require the
developer to make extensive changes, but it would require
them to know ahead of time which classes they wanted to
instrument and which they didn't. I feel pretty strongly
that there needs to be a way to (easily and automatically)
instrument any non-sealed class.

I have a couple of almost-solutions but none of them quite
work.

1) The AppDomain could support an event much like
TypeResolve except that it allows the event handler to
return a Type object rather than an Assembly object. I
can't find such an event and I can't figure out how to use
TypeResolve to accomplish the same thing, although it
might be possible. Also, TypeResolve only fires when the
CLR can't resolve the type on its own, instead of always.
Is there a way to trick TypeResolve into always firing?

2) Override the new operator. But this isn't allowed.

3) Create a subclass of Type that overrides
CreateInstance, GetConstructor, etc. I can't figure out
how to get the CLR to use this type object instead of the
base-class's type object. Also, this could have lots of
unintended consequences. But at the moment, it seems like
the only thing that might work.

4) Bend my rule a little bit and only support
instrumenting of objects created with
Activator.CreateInstance(). This is kind of ugly, but at
least it would keep the developer free to decide later
what to instrument if *all* uses of 'new' were replaced
with Activator.CreateInstance().

Any ideas or suggestions? Thanks.

- Ben Blair
- benblair@ Association for Computing Machinery dot org
 
Ben Blair said:
Hi All,

I'm looking for a way to cause type instantiation to call
a custom class factory instead of having the CLR create an
instance of the type on its own. Specifically, I need to
return a subclass instance when a new base class instance
is requested.

You can do this by creating a static method of the base class type and by
defining all constructors to be non-public.

There is no magical way to redefine the language to call your own class
factory.
 
Yes, you can intercept type instantiation in .NET.

suggestion: get the book by Don Box called "Essential .NET"

In it there is a good discussion of the CLR and the .NET mechanisms for
interception, including the concepts of TransparentProxy, RealProxy, and
ContextBoundObject, and how to apply these capabilities using attributes.
You could do something like this:

[MyInterceptor]
public class MyClass : ContextBoundObject {
}

and instantiations (and all other method calls) would be intercepted by the
MyInterceptor code.


Some links related to this:
http://www.hoppersoft.com/Andy/PermaLink.aspx/48168b49-6ae9-4833-95b2-d6bc64f5bb1d
http://blogs.gotdotnet.com/cbrumme/PermaLink.aspx/24e9e5f5-9923-4cf9-b097-9c018c69d5cb
http://msdn.microsoft.com/msdnmag/issues/03/03/ContextsinNET/default.aspx

an instructional video describing the topic:
http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20030422NETFXDP/manifest.xml

But danger! perf implications
http://urbanasylum.dynu.com/JustTheFacts/archives/000068.html


Cheers,
-Dino

also
http://www.gotdotnet.com/team/dbox/spoutlet.aspx?key=2002-11-24T22:16-08:00
 
Back
Top