Another diversion before getting back to actual Promise language syntax description, this time trying to reproduce the Promise IoC syntax in C#. Using generics gets us a good ways there, but we do have to use a static method on a class as the registrar giving us this syntax:
$#[Catalog].In(:foo).Use<DbCatalog>.ContextScoped;
// becomes
Context._<ICatalog>().In("foo").Use<DbCatalog>().ContextScoped();
Not too bad, but certainly more syntax noise. Using a method named _ is rather arbitrary, i know, but it at least kept it more concise. Implementation-wise there's a lot of assumptions here: This approach forces the use of interfaces for Promise types, which can't be enforced by generic constraints. It would also be fairly simple to pre-initialize the Context with registrations that look for all interfaces IFoo and then find the implementor Foo and register that as the default map, mimicking the default Promise behavior by naming convention instead of Type/Class name shadowing.
Next up, instance resolution:
var foo = Foo(); // becomes var foo = Context.Get<IFoo>();
This is where the appeal of the syntax falls down, imho. At this point you might as well just go to constructor injection, as with normal IoC. Although you do need that syntax for just plain inline resolution.
And the whole thing uses a static class, so that seems rather hardcoded. Well, at least that part we can take care of: If we follow the Promise assumption that a context is always bound to a thread, we can use [ThreadStatic] to chain context hierarchies together so that what looks like a static accessor is really just a wrapper around the context thread state. Given the following Promise syntax:
context(:inner) {
$#[Catalog].In(:inner).ContextScoped;
$#[Cart].ContextScoped;
var catalogA = Catalog();
var cartA = Cart();
context {
var catalogB = Catalog(); // same instance as catalogA
var catalogC = Catalog(); // same instance as A and B
var cartB = Cart(); // different instance from cartA
var cartC = Cart(); // same instance as cartB
}
}
we can write it in C# like this:
using(new Context("inner")) {
Context._<ICatalog>().In("inner").ContextScoped();
Context._<ICart>().ContextScoped();
var catalogA = Context.Get<ICatalog>();
var cartA = Context.Get<ICart>();
using(new Context()) {
var catalogB = Context.Get<ICatalog>(); // same instance as catalogA
var catalogC = Context.Get<ICatalog>(); // same instance as A and B
var cartB = Context.Get<ICart>(); // different instance from cartA
var cartC = Context.Get<ICart>(); // same instance as cartB
}
}
This works because Context is IDisposable. When we new up an instance, it takes the current threadstatic and stores it as it's parent and sets itself as the current. Once we leave the using() block, Dispose() is called, at which time, we set the current context's parent back as current, allowing us to build up and un-roll the context hierarchy:
public class Context : IDisposable {
...
[ThreadStatic]
private static Context _current;
private Context _parent;
public Context() {
if(_current != null) {
_parent = _current;
}
_current = this;
}
public void Dispose() {
_current = _parent;
}
}
I'm currently playing around with this syntax a bit more and using Autofac inside the Context to do the heavy lifting. If I find the syntax more convenient than plain Autofac, i'll post the code on github.
Before I get into the code samples, I should point out one more "construction" caveat and change from my previous writing: Constructors don't have to be part of the Type. What does that mean? If you were to explictly declare the Song Type and excluded the Song:(name) signature from the Type, it would still get invoked if someone were to call Song{name: "foo"}, i.e. given a JSON resolution call, the existence of fields is used to try to resolve to a constructor, resulting in a call to Song:(name). Of course that's assuming that instance resolution actually hits construction and isn't using a Use lambda or returning an existing ContextScoped instance.
Let's assume we have some persistence layer session and that it can already fetch DTO entities, a la ActiveRecord. Now we want to add a repository for entities fetched so that unique entities from the DB always resolve to the same instance. A simple solution to this is just a lookup of entities at resolution time:
$#[Session].In(:session).ContextScoped;
$#[Dictionary].In(:session).ContextScoped;
$#[User].Use {
var rep = Dictionary<string,User>();
var name = $_.name;
rep.Get(name) ?? rep.Set(name,Session.GetByName<User>(name));
};
In the above the $_ implicit JSON initializer argument is used to determine the lookup value. I.e. given a JSON object, we can use dot notation to get to its fields, such as $_.name. This name is then used to do a lookup against a dictionary. Promise adopts the C# ?? operator to mean "if nil, use this value instead", allowing us to call .Set on the dictionary with the result from the Session. There is no return since the last value of a lambda is returned implicitly and Set returns the value set into it.
One other thing to note is the registration of Dictionary as ContextScoped. Since Dictionary is a generic type, each variation of type arguments will create a new context instance of Dictionary. For our example this means that the lambda executed for User resolution always gets the same instance of the dictionary back here.
context(:session) {
var from = User{ name: request.from };
var to = User{ name: request.to };
var msg = Message{ from: from, to: to, body: request.body };
msg.Send();
}
The usage of our setup stays nice and declarative. Gettting User instances has no knowledge how the instance is created and just passes what instance it wants, i.e. one named :name. Swapping out the resolution behavior for a service layer to get users, a mock layer to test the code, a different DB layer, all can be done without changing the business logic operating on the User instances.
Of course the above repository is just a dictionary and only supports getting. It assumes that Session<User>.GetByName will succeed and even then only acts as a session cache. So let's create a simple Respository class that also creates new entities and let's them be saved.
class Repository<TEntity> {
Session _session = Session(); // manual resolve/init
+Dictionary<String,Enumerable> _entities; // automatic resolve/init
Get:(name|TEntity) {
var e = entities[name] ?? _entities.Set(name,_session.GetByName<TEntity>(name) ?? TEntity{name});
e.Save:() { _session.Save(e); };
return e;
}
}
Since the Repository class has dependencies of its own, this class introduces dependency injection as well. The simplest way is to just initialize the field using the empty resolver. In other languages this would be hardcoding construction, but with Promise this is of course implicit resolution against the IoC. Still, that's the same extraneous noise as C# and Java that I want to stay away from, even if the behavior is nicer. Instead of explicitly calling the resolver, Promise provides the plus (+) prefix to indicate that a field should be initialized at construction time.
The work of the repository is done in Get, which takes the name and returns the entity. As before, it does a lookup against the dictionary and otherwise set an instance into the dicitionary. However, now if the session returns nil, we call the entity's resolver with an initializer. But if we set up the resolver to call the repository, doesn't that just result in an infinite loop? To avoid this, Promise will never call the same resolver registration twice for one instance. Instead, resolution bubbles to next higher context and its registration. That means, lacking any other registration, this call will just create a new instance.
Finally, we attach a Save() method to the entity instance, which captures the session and saves the entity back to the DB. This last bit is really just there to show how entities can be changed at runtime. As repositories goes, it's actually a bad pattern and we'll fix it in the next iteration.
$#[Repository].In(:session).ContextScoped;
$#[User].Use { Repository().Get($_.name); };
The registration to go along with the Repository has gotten a lot simpler as well. Since the repository is context scoped and gets a dictionary and session injected, these two Types do not need to be registered as context scoped themselves. And User resolution now just calls the Repository getter.
context(:session) {
var user= User{ name: request.name };
user.email = request.email
user.Save();
}
The access to the instance remains unchanged, but now we can change its data and persist it back using the Save() method.
As I mentioned, the attaching of Save() was mostly to show off monkey-patching and in itself is a bad pattern. A true repository should just commit for us. So let's change the repository to reflect this:
class Repository<TEntity> {
+Session _session;
+Dictionary<String,Enumerable> _entities;
_rollback = false;
Get:(name|TEntity) {
var e = entities[name] ?? _entities.Set(name,_session.GetByName<TEntity>(name) ?? TEntity{name});
return e;
};
Rollback:() { _rollback = true; };
~ {
_entities.Each( (k,v) { _session.Save(v) } ) unless _rollback;
}
}
By attaching a Disposer to the class, we get the opportunity to save all instances at context exit. But having automatic save at the end of the :session context, begs for the ability to prevent commiting data. For this the Rollback() method simply sets a _rollback flag that governs whether we call save on the entities in the dictionary.
context(:session) {
var user= User{ name: request.name };
user.email = request.email
}
We've iterated over our repository a couple of times, each time changing it quite a bit. The important thing to note, however, is that the repository itself, as well as the session, have stayed invisible from the business logic. Both are an implementation detail, while the business logic itself just cared about retrieving and manipulating users.
I hope that these past posts give a good overview of how language level IoC is a simple, yet powerful way to control instance lifespan and mapping without cluttering up code. Next time, i'll return to what can be done with methods, since fundamentally Promise tries to keep keywords to a minimum and treat everything as a method/lambda call.
This is a post in an ongoing series of posts about designing a language. It may stay theoretical, it may become a prototype in implementation or it might become a full language. You can get a list of all posts about Promise, via the Promise category link at the top.
Before I can get into mapping, I need to changed the way I defined getting an instance in Type and Class definition:
When I talked about Object.new, I eluded to it being a call on the Type, not the Class and the IoC layer taking over, but I was still trapped in the constructor metaphor so ubiquitous in Object Oriented programming. .new is really not appropriate, since we don't know if what we are accessing is truly new. You never call a constructor, there is no access to such a beast, instead it can best be thought of an instance accessor or instance resolution. To avoid confusing things further with a loaded term like new, I've modified the syntax to this:
// get an instance var instance = Object();
We just use the Type name followed by empty parentheses, or in the case that we want to pass a JSON initializer to the resolution process we can use:
// get an instance w/ initializer
var instance = Object{ foo: "bar" };
As before, this is a call against the implicit Type Object, not the Class Object. And, also as before, creating your own constructor intercept is still a Class Method, but now one without a named slot. The syntax looks like this (using the previous post's example):
Song:(name) {
var this = super;
this._name = name;
return this;
}
The important thing to remember is that the call is against the Type, but the override is against the Class. As such we have access to the constructor super, really the only place in the language where this is possible. Being a constructor overload does mean, that a call to Song{ ... } will not necessarily result in a call to the Song class constructor intercept, either because of type mapping or lifespan managment, but i'm getting ahead of myself.
Confused yet? The Type/Class overlapping namespace approach does seem needlessly confusing when you start to dig into the details, but I feel it's a worthwhile compromise, since for the 99% use case it's an invisible distinction. Hopefully, once I work through everything, you shouldn't even worry about there being a difference between Type and Class — things should just work, or my design is flawed.
In the spirit of poking into the guts of the design and explaining how this all should work, I'll stop hinting at the resolution process and instead dig into the actual usage of the context system.
// creates new instance of class User by default
var song = User{name: "bob"};
This call uses the implicit mapping of the User type to class and creates a new User class instance. If there is no intercept for the User() Class Method, the deserializer construction path is used and if there exists a field called _name, it would be initialized with "bob".
// this happens implicitly $#[User].Use<User>; // first one is the Type, the second is the Class // Injecting a MockUser instance when someone asks for a User type $#[User].Use<MockUser>;
Promise uses the $ followed by a symbol convention for environment variables popularized by perl and adopted by php and Ruby. In perl, $ actually is the general scalar variable prefix and there just exist certain system populated globals. In Promise, like Ruby, $ is used for special variables only, such as the current environment, regex captures, etc. $# is the IoC registry. Using the array accessor with the Type name accesses the registry value for that Type, which we call the method Use<> on it.
The Use<> call betrays that Promise support a Generics system, which is pretty much a requirement the moment you introduce a Type system. Otherwise you can't create classes that can operate on a variety of other typed instances without the caller having to cast instances coming out to what they expect. Fortunately Generics only come into play when you have chosen typed instances, otherwise you just treat them as dynamic duck-typed instances that you can call whatever you want on.
The above mapping is a straight resolution from a Type of a class. But sometimes, you don't want a one-to-one mapping, but rather want a way to dynamically execute some code to make runtime decisions about construction. For this, you can use the lambda signature of .Use:
$#[User].Use {
var this = Object $_;
this:Name() { return _name; };
return this;
};
The above is a simple example of how a dynamic type can be built at runtime to take the place of a typed instance. Of course any methods promised by User not implemented on that instance will result in a MethodMissing runtime exception on access.
The $_ environment variable is the implict capture of the lambda's signature as a JSON construct. This allows our mapping to access whatever initializer was passed in at resolution access.
$#[User].Use { return MockUser $_; };
The above example looks like it's the same as the $#[User].Use<MockUser> example, but it has the subtle difference that MockUser in this scenario is the Type, not the Class. If MockUser were mapped as well, the resolved instance would be of another class.
But you don't have to create a new instance in the .Use lambda, you could do something like this:
// Don't do this!
var addressbook = AddressBook();
$#[AddressBook].Use { return addressbook; };
This will create a singleton for AddressBook, but it's a bad pattern, being a process-wide global. The example only serves to illustrate that .Use can take any lambda.
So far, mapping just looks like a look-up table from Type to Class, and worse, one that is statically defined across the executing process. Next time I will show how the IoC container isn't just a globally defined Class mapper. Using nested execution context, context specific mappings and lifespan mappings, you can easily created factories, singletons and shared services, including repositories, and have those definitions change depending on where in your code they are accessed.
This is a post in an ongoing series of posts about designing a language. It may stay theoretical, it may become a prototype in implementation or it might become a full language. You can get a list of all posts about Promise, via the Promise category link at the top.
Before continuing with additional forms of method defintions, I want to take a detour through the Inversion of Control facilities, since certain method resolution behavior relies on those facilities. IoC is one feature of Promise that is meant to not be seen or even thought about 99% of the time, but when you need to manipulate its default behavior it is a fairly broad topic, which I will cover in the next 3 or 4 posts. If you want to see code, you probably want to just go to the next post, since this one is mostly about the reasoning for inclusion of IoC in the language itself.
Not too long Garbage Collection was considered the domain of academic programming. My first experience with it was writing LISP on Symbolics LISP machines. And while it was a wonderful development experience, you got used to the Listener (think REPL on LISP machines) to pause and the status Genera status bar blinking with (garbage-collect). Ok, but that's back on hardware significantly less powerful than my obsolete Razor flip-phone.
These days garbage collection is pretty much a given. The kind of people that say you have to use C to get things done are the same kind of people that used to say that you have to use assembly to get things done, i.e. they really are talking about edge cases. Even games are using scripting languages for much of their game logic these days. Whether it's complex generational garbage collection or simple reference counting, most languages are memory managed at this point.
But still we have the legacy of malloc and free with us. We still new-up instances and while there's fairly little use of destructors, we still run into scenarios that require decomissioning of objects before garbage collection gets rid of them. And while on the subject of construction and destruction, we're still manually managing the lifespan from creation to when we purposely let them drop out of scope so GC can do its magic.
Somehow while moving to garbage collection so that we don't have to worry about that plumbing, we kept the plumbing of manually handling construction, initialization and disposal. That doesn't seem like work related to solving the task at hand, but rather more like ceremony we've grown used to. We now have three phases in an instance lifespan, only one of which is actually useful to problem solving:
Depending on which language you are using, this might be a single constructor stage (Java, C#, Ruby, et al) or an allocation and initialization stage (Smalltalk, Objective-C, et al). Either way, you do not want your code to start interacting with the instance until these stages are completed
This is the useful stage of the instance, when it actually can fullfill its purpose in our program. This should really be the only stage we ever need to see.
We're done with the instance, so we need to clean up any references it has and resources it has a hold of and let the garbage collector do the rest. By definition, it has passed its useful life and we just want to make sure it's not interfering with anything still executing.
Complicating disposal is that most garbage collected languages have non-deterministic destructors, which are not invoked until the time of collection and may be long after use of the instance has ceased. Since there are scenarios where clean-up needs to happen in a deterministic fashion (such as closing file and network handles), C# added the IDisposable pattern. This pattern seems more like a "oh, crap, what do we do about deterministic cleanup?" add-on than a language feature. It completely puts the onus on the programmer both for calling .Dispose (unless in a using block) and for handling access to an already disposed instance.
For the most part, all we should care about is that when we want an instance with certain capabilities, we should be able to get access to one. Who cares if it was freshly constructed or a shared instance or a singleton or whatever. Those are details that are important but once defined not part of the user story we set out to satisfy.
In Java and C#, this need for pushing instance management out of the business logic and into dedicated infrastructure led to the creation of Inversion of Control containers, named thus because they invert the usual procedural flow of "create an object, hand it to another object constructor as a dependency, etc." to "ask for the object you need and the depedency chain will be resolved for you". There are numerous articles on the benefits of Dependency Injection and Inversion of control. One of the simplest explanation was given by John Munch to the Stackoverflow question "How to explain Dependency Injection to a 5-year-old":
When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn't want you to have. You might even be looking for something we don't even have or which has expired.
What you should be doing is stating a need, "I need something to drink with lunch," and then we will make sure you have something when you sit down to eat.
But IoC goes beyond the wiring-up of object graphs that DI provides. It is also responsible for knowing when to hand you a singleton vs. a shared instance for the current scope vs. a brand new instance and handles disposal of those instance as their governing scopes are exited.
These frameworks are build on top of the existing constructor plumbing and use reflection to figure out how to take over the tasks that used to fall to the programmer. For Promise this plumbing is considered a natural extension of what we already expect of garbage collection and tries to be automatic and invisible.
By default every "constructor" access to an instance resolves the implicit Type to the Class of the same name, and creates an instance, i.e. behavior as you expect from OO languages. However, using nested execution scopes, lifespan management and Type mapping, this behavior can be modified without touching the business logic. In the next post, I'll start by explaining how the built in IoC works by tackling Type/Class mapping.
This is a post in an ongoing series of posts about designing a language. It may stay theoretical, it may become a prototype in implementation or it might become a full language. You can get a list of all posts about Promise, via the Promise category link at the top.
Only 3 posts into the definition of the language and already I'm changing previously published specs. Well, that's the way it goes.
I'm currently writing the article about language level IoC which I eluded to previously, but the syntax effects I had not fully considered yet. The key concept, tho, is that there is no construction, there is only instance resolution, which .new being a call on the Type not Class hinted at. But that does mean that what you get does not necessarily represent a new instance.
And beyond naming implications, the implications of what arguments passed into the resolution call mean is also ambiguous. The could be initialization values or they could be arguments to determine which instance of that Type to fetch (like in a Repository pattern). And if that's the case, the overloading this process becomes tricky as well, since it should access the super class, which means it only makes sense in the construction paradigm.
Basically lots of syntactic implications I'm working through right now. The only thing that is certain is that .new will not make it through that review process.
This is a post in an ongoing series of posts about designing a language. It may stay theoretical, it may become a prototype in implementation or it might become a full language. You can get a list of all posts about Promise, via the Promise category link at the top.
I’ve been on a bit of a tear about declaring dependency contracts and injecting only what is required. While examining the use of Interfaces in IoC and their shortcomings, I decided that taken to the extreme, dependencies come down to call dependencies, which could be modeled with delegates rather than interfaces. Instead of writing a novel, as I’ve been prone to, i thought I’d do a shorter post on my approach to this solution, and expand on the implementation in later posts.
To recap, in the SOLID principles, the Interface Segregation Principle states: Clients should not be forced to depend upon interfaces that they do not use. This means that interfaces should be fine-grained enough to expose no more than one responsibility. Taken to the extreme, this could be taken to mean that each interface only has a single method. There are valid SRP scenarios where a responsibility is modeled by more than one call, but let’s start with the simplest scenario first, then see how well it applies to more complex responsibilities later.
In C# we have delegates, which describe a single method call. A delegate instance is a reference to a method that encapsulates a specific instance of a class, without exposing the underlying class (unless your delegate is a static method). A delegate can even be used to expose internal, protected and private methods.
Instead of declaring a list of interfaces that the IoC container should inject, classes would define their dependencies as delegates. Taking the example from my duck typing post, we would get the following dependency declarations.
First, we have the same service provider, MessageQueue, which still doesn’t need to implement an interface:
public class MessageQueue
{
public void Enqueue(string recipient, string message) { ... }
public string TryDequeue(string recipient) { ... }
}
Next, we have the new Producer, now declaring its dependency has a delegate:
public class Producer : IProducer
{
public delegate void EnqueueDelegate(string recipient, string message);
public Producer(EnqueueDelegate dispatcher) { ... }
}
And finally, we have the new Consumer, also declaring a delegate for construction time injection:
public class Consumer : IConsumer
{
public delegate string TryDequeueDelegate(string recipient);
public Consumer(TryDequeueDelegate inbox) { ... }
}
Think of the delegate as your Method Interface. You could define your dependencies as Func‘s and Action‘s, but that would obfuscate your dependencies beyond recognition in most scenarios. By using an explicit delegate, you get to attach the dependency to the class that has the dependency, in addition to having a descriptive signature.
Now, if we were to wire this up manually we’d get something like this:
var queue = new MessageQueue(); IProducer producer = new Producer(queue.Enqueue); IConsumer consumer = new Consumer(queue.TryDequeue);
That’s simple enough, but not really very scalable, once you get a lot of dependencies to wire up. What we really need is an IoC container that let’s us register delegates against classes, instead of having to have instances at dependency declaration time. Delegates can’t be cast from one to another and are not, strictly speaking, types, which posts some challenges with creating a type-safe registration interface. There are a number of ways to accomplish this syntax, which I will elaborate on in my next post.
Recently, I’ve had a need to create proxy objects in two unrelated projects. What they had in common was that they both dealt with .NET Remoting. In one it was traditional Remoting between machines, in the other working with multiple AppDomains for Assembly flexibility. In both scenarios, I had a need for additional proxies other than the Remoting created Transparent proxy and the Castle project‘s DynamicProxy proved invaluable and versatile. It’s a bit sparse on documentation, but for the most part, you should be able to figure things out by playing with it and lurking around their forum.
If you’re not familiar with the Castle project, check it out, because DynamicProxy is really only a supporting player in an excellent collection of useful tools. From their Inversion of Control Containers MicroKernel/Windsor to MonoRail and ActiveRecord (built on NHibernate), there is a lot there that can make your life easier.
But why would I need to create proxies, when the Remoting infrastructure in .NET takes care of this for you with Transparent Proxies? Well, let me describe both scenarios:
From my experience with .NET Remoting, it’s dead simple to do something simple. But it really is best suited for WebService stateless calls, because there isn’t a whole lot exposed to add quality of service plumbing. The transparent proxy truly is transparent until something fails. Same is true on the server side, where you don’t get a lot of insight into the clients connected to you.
And then there are events, which, imho, are one of the greatest thing about doing client/server programming with Remoting. Those are painful in two ways, having to have a MarshalByRefObject helper proxy the event calls and pruning dead clients on the server which you won’t find out about until you try to invoke their event handler.
But those shortcomings are not enough reason to fall back to sockets and custom/stateful wire protocols. Instead I like to wrap my transparent proxy in another proxy that has all the plumbing for maintaining the connection, pinging the server and intelligently handling failure. Originally I created them by hand, but I just converted my codebase over to use DynamicProxy the other day.
Using CreateInterfaceProxyWithoutTarget and having the proxy derive from my plumbing baseclass automagically provides me with an object that looks like my target interface by wraps the Remoting proxy with my quality of service code.
public static RemotingClient<T> GetClient(Uri uri) { Type t = typeof(T); ProxyGenerator g = new ProxyGenerator(); ProxyGenerationOptions options = new ProxyGenerationOptions(); options.BaseTypeForInterfaceProxy = typeof(RemotingClient<T>); RemotingClient<T> proxy = (RemotingClient<T>)g.CreateInterfaceProxyWithoutTarget( t, new Type[0], options, new ProxyInterceptor<T>()); proxy.Uri = uri; return proxy; }
I’ll do another post later just on Remoting, since the whole business of getting events to work was a bit of a labor and isn’t documented that well.
The second project started with wanting to be able to load and unload plug-ins dynamically and has now devolved into a framework for auto-updating components of an App at runtime.
This involves loading the assemblies providing the dynamic components into new AppDomains, so that we can unload the assemblies again by unloading the AppDomain. Instances of the components class are then marshaled across the AppDomain boundary by reference so that the main AppDomain never loads the dynamic assembly. This way, when a component needs to be updated, I can dump that AppDomain and recreate it.
The resilience of the connection isn’t in question here, although there is need for quite a bit of plumbing to get references to the remoted components disposed before the AppDomain can be unloaded. Again, a DynamicProxy can help on the main AppDomain side by acting as a facade to the actual reference, so that you can reload the underlying assembly and recreate the reference without the main application having to be aware of it.
But I haven’t gotten that far, nor have I decided whether that would be the best way, rather than an explicit disposal and recreation of the references.
Where DynamicProxy comes to a rescue here is when your object to be passed across the boundary isn’t derived from MarshalByRefObject. This could be a scenario, where you are trying to use a component that’s already derived from another baseclass, so adding MarshalByRefObjectisn’t an option. Now DynamicProxy with its ability to provide a baseclass for the proxy gives you a sort of virtual multiple inheritance.
This is also an ideal scenario for using Castle.Windsor as the provider of the component. Using IoC, I was able to create a generic common dll that contains all the interfaces as well as a utility class for managing the components that need to be passed across the boundary, this class never has to know anything about the dynamic assembly, other than that the assembly stuffs its components into the AppDomain’s Windsor container.
The resulting logic for creating an instance that can be marshaled across AppDomain boundaries looks something like this:
public T GetInstance<T>() { Type t = typeof(T); if (!t.IsInterface) { throw new ArgumentException("Type must be an interface"); } try { T instance = container.Resolve<T>(); if (typeof(MarshalByRefObject).IsAssignableFrom(instance.GetType())) { return instance; } else { ProxyGenerator generator = new ProxyGenerator(); ProxyGenerationOptions generatorOptions = new ProxyGenerationOptions(); generatorOptions.BaseTypeForInterfaceProxy = typeof(MarshalByRefObject); return (T)generator.CreateInterfaceProxyWithTarget(t, instance, generatorOptions); } } catch (Castle.MicroKernel.ComponentNotFoundException) { return default(T); } }
All in all, DynamicProxy is something that really should be part of the .NET framework. Proxying and Facading patterns are just too common to only support them via the heavier and MarshalByRefObject dependent remoting infrastructure.
The version of DynamicProxy I was using was DynamicProxy2, which is part of the Castle 1.0 RC3 install. It’s a lot more versatile than the first DynamicProxy and deals with generics, but mix-ins are not yet implemented in this version. However, if you just need a single mix-in, specifying the base class for your proxy can go a long way to solving that limitation.