Caliburn.Micro - resolving ViewModels from IoC container using Castle.Windsor
I'm using 开发者_高级运维Caliburn.Micro to build a composite UI app, and have decided to use Castle Windsor to build ViewModel objects, so that any services they need to operate can be injected automatically and avoid the servicelocator anti-pattern.
The problem is that Castle Windsor is using property injection to set the ActiveItem
property of my viewmodel objects to (seemingly the first component it finds that matches the IScreen
service) as it resolves them.
I don't want it to do this, because I want to set the active screen myself by calling ActivateItem()
when I've worked out which viewmodel I want to render a view for.
It doesn't look like Castle Windsor can be made to not perform property injection (I'm using the fluent registration API with IWindsorInstaller
classes), so what is a good approach to take here?
Should I not be resolving ViewModel objects from the container? If not, what's a good approach to avoid the servicelocator anti-pattern?
Many thanks in advance.
What seems to have worked for the time being, is the following:
_container.Kernel.ComponentModelCreated += model =>
{
IEnumerable<PropertySet> nonInjectableProperties = model.Properties
.Where(set => set.Property.Name == "ActiveItem").ToList();
foreach (PropertySet nonInjectableProperty in nonInjectableProperties)
{
model.Properties.Remove(nonInjectableProperty);
}
}
Essentially this is intercepting the resolution of the component and removing one of the properties from it, such that when the component is resolved, the kernel no longer sees an "ActiveItem" property to lookup a dependency for.
To turn off property injection throughout the whole container, try the following:
container.Kernel.ComponentModelBuilder.RemoveContributor(container.Kernel.ComponentModelBuilder.Contributors.OfType<PropertiesDependenciesModelInspector>().Single());
精彩评论