I was wondering if anyone had any thoughts on extending MicroKernel/Windsor to allow support for .NET 4's new Type Equivalence feature. If you aren't familiar with this, it allows the CLR to treat interfaces (as well as enums and structs, I believe) that were defined in different assemblies as though they are of the same type, as long as certain attributes have been applied to them. A good demonstration of the feature is available here: http://blogs.msdn.com/mshneer/archive/2008/10/28/advances-in-net-type-system-type-equivalence-demo.aspx
I've done some basic tests to see how Windsor will react when a component is registered using an interface defined in one assembly and resolved using an equivalent type defined in another assembly. I set up a solution containing three projects: a host application and two DLLs. None of the projects references the other directly. In each project I defined an identical interface, ICommonInterface, to which I applied the required attributes to enable type equivalence. In the two DLL projects, I also provided implementations of ICommonInterface. In the host application, I loaded both DLLs at runtime and used the fluent registration API to register all types implementing ICommonInterface (using the host's version of it). I then tried to see if the container could resolve any instance of ICommonInterface (again, using the host's version of it). Here's what I found: - Attempting to call Resolve<ICommonInterface>() failed. Looking through the code, it appears that this is because the different versions of ICommonInterface have different Type instances, so a lookup on the service2Handler dictionary in the DefaultNamingSubSystem (which uses Type as the key) will fail. - However, calling ResolveAll<ICommonInterface>() returned an instance of both registered classes. I believe this is because it ultimately uses GetAssignableHandlers() on the naming subsystem, which uses Type.IsAssignableFrom() to check for a match instead of an equality check between the types. Presumably, .NET 4 modified IsAssignableFrom() to respect type equivalence. >From what I can tell, it seems to be possible to get MicroKernel to respect type equivalence by providing a custom IEqualityComparer<Type> implementation to the various dictionaries that use Type as a key in the naming subsystem (and potentially a modification to GetHandlers(Type) to use the same comparer instead of the == operator). Here's the one I used: public class TypeEquivalenceComparer : EqualityComparer<Type> { public override bool Equals(Type x, Type y) { if (ReferenceEquals(x, y)) return true; if (x == null || y == null) return false; return x.IsEquivalentTo(y); } public override int GetHashCode(Type obj) { return obj.GUID.GetHashCode(); } } Unfortunately, I haven't seen any good way of extending the DefaultNamingSubSystem implementation to change just this behavior. I had to copy the entire body of the class to make my changes. The main problem is that a subclass can't replace the dictionaries with new ones using the custom comparer because all of them are readonly and two of them are private. It would be a pretty simple change to the implementation to allow a custom IEqualityComparer<Type> implementation to be provided as an optional constructor argument. If anyone thinks this is a good idea, I should be able to supply a patch for it. Does anyone have any opinions on this? Thanks, Michael Davis -- You received this message because you are subscribed to the Google Groups "Castle Project Development List" group. To post to this group, send email to castle-project-de...@googlegroups.com. To unsubscribe from this group, send email to castle-project-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en.