Actually this could be good time to refactor DefaultNamingSubSystem away
from storing services by strings, and store them by custom HandlerToken
or something, that could be aware of the type equivalence.
Krzysztof
On 2010-03-22 20:06, Michael Davis wrote:
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.
--
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.