Most of the examples I see for Castle Windsor to do auto-register of
types depend on deriving from some IFoo. Or, from base class. However,
I often have simple components (services) that just require IFoo in
the constructor:
public class AddressViewModel
{
public AddressViewModel(ICountryRepository countries)
{
this.Countries = countries.GetAll();
}
}
Here AddressViewModel is created by ASP.NET MVC generic ActionFilter
that transforms domain model into view model - automatically. It asks
Windsor to create the destination view model. I have many view models,
and I don't really want to manually register all of them in Windsor.
>From my point of view, if I ask Windsor to create AddressViewModel, it
should check if its constructor has registered dependencies (maybe
even nested), and if so - create them and then create AddressViewModel
- instead of throwing "not registered".
How do I make Windsor to automatically register/recognize such cases?
I see two ways:
1. Browse all types in assembly, get their constructors, check if any
of the constructor's parameter is registered in Windsor... and
register it. The problem is that Service can depend on Service2 ->
IFoo... I want CONTAINER to do this, not me.
2. Somehow extend Windsor (facility, etc - I'm not expert here) so
that the above happens during "Resolve" call - so that I don't need to
browse all the meaningless types in all assemblies.
In both cases, however, I'll need a way to ask Windsor "Is type T your
dependency - directly or indirectly via nested constructor?".
I really hate duplication, so I don't see why I need to manually
register something that Windsor does already know about and can
create.
Here's the code that I use now. I'm really not expert in Windsor so
I'm not sure if the code is OK - but it works.
var dependencies = container.Kernel.GetAssignableHandlers(typeof
(object));
// for all ViewModel classes - purely optimization, to avoid
browsing all types
foreach (var type in typeof(ViewModel<>).Assembly.GetTypes().Where
(x => x.Name.EndsWith("ViewModel")))
{
// get all constructors and their parameters
var ctorArgs = type.GetConstructors().SelectMany(x =>
x.GetParameters());
// ViewModel can be resolved if any of its ctors has Windsor-
registered arguments
// TODO: add checks for IList<Type>, etc... really Windsor
should do this
var canBeResolved = dependencies.Any(dep => ctorArgs.Any(a =>
a.ParameterType.IsAssignableFrom
(dep.ComponentModel.Service)));
if (canBeResolved)
container.AddComponent("viewModel" + type.Name, type);
}
However, I would better have Windsor (or my extension) do this during
resolve-time, because brosing ALL types is a bit overkill in my
opinion, even though I narrow it with name filter. Is it possible? Is
there a better way?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Castle Project Users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/castle-project-users?hl=en
-~----------~----~----~----~------~----~------~--~---