Say we have several assemblies, and they all implement IAnimal, and we'd like go to one place to find out about the presence of the other IAnimal imple开发者_开发知识库mentation.
features:
we don't want pre-knowledge outside of an assembly
there could be a register class / method within the assembly
it is preferable not to use reflection. So far this seems to be the only way though
discussion:
I imagined doing this statically via inheritance, however, I'm not aware of an assembly level initialization sequence.
I suggest taking a look at MEF. It is practically designed for this kind of thing.
It does use reflection, as this is the mechanism created for such dynamic discovery. I doubt you will find a solution that doesn't use some level of reflection.
When starting your app you could register to the AssemblyLoad of your AppDomain:
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(NewAssemblyLoaded);
and define NewAssemblyLoad to add the IAnimal implementations to a list of Types (e.g. animalTypes) you maintain:
static void NewAssemblyLoaded(object sender, AssemblyLoadEventArgs args)
{
Assembly anAss = args.LoadedAssembly;
foreach (Type t in Assembly.GetTypes())
{
if (!t.IsInterface && typeof(IAnimal).IsAssignableFrom(t))
animalsList.Add(t);
}
}
I've written an extension method which allows you to look up deployed Types which match certain criteria at runtime - it does use Reflection, but you may find it useful.
IEnumerable<Type> animalTypes = Assembly.GetExecutingAssembly()
.GetAvailableTypes(
typeFilter: t => !t.IsInterface && typeof(IAnimal).IsAssignableFrom(t));
精彩评论