Created
August 5, 2011 16:29
-
-
Save bryanhunter/1127914 to your computer and use it in GitHub Desktop.
Castle bootstrapper for Caliburn.Micro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Hooks up Castle Windsor as the container for your Caliburn.Micro application. | |
// Turns on support for delegate factory methods (e.g. passing the factory "Func<XyzEditViewModel>" as a constructor arg) | |
// Dependencies: In addition to Caliburn.Micro you will need to reference Castle.Core and Castle.Windsor | |
public class CastleBootstrapper<TRootViewModel> : Bootstrapper<TRootViewModel> | |
{ | |
private ApplicationContainer _container; | |
protected override void Configure() | |
{ | |
_container = new ApplicationContainer(); | |
_container.AddFacility<TypedFactoryFacility>(); | |
} | |
protected override object GetInstance(Type service, string key) | |
{ | |
return string.IsNullOrWhiteSpace(key) | |
? _container.Resolve(service) | |
: _container.Resolve(key, service); | |
} | |
protected override IEnumerable<object> GetAllInstances(Type service) | |
{ | |
return (IEnumerable<object>)_container.ResolveAll(service); | |
} | |
protected override void BuildUp(object instance) | |
{ | |
instance.GetType().GetProperties() | |
.Where(property => property.CanWrite && property.PropertyType.IsPublic) | |
.Where(property => _container.Kernel.HasComponent(property.PropertyType)) | |
.ForEach(property => property.SetValue(instance, _container.Resolve(property.PropertyType), null)); | |
} | |
} | |
public class ApplicationContainer : WindsorContainer | |
{ | |
public ApplicationContainer() | |
{ | |
Register( | |
Component.For<IWindowManager>().ImplementedBy<WindowManager>().LifeStyle.Is(LifestyleType.Singleton), | |
Component.For<IEventAggregator>().ImplementedBy<EventAggregator>().LifeStyle.Is(LifestyleType.Singleton) | |
); | |
RegisterViewModels(); | |
} | |
private void RegisterViewModels() | |
{ | |
Register(AllTypes.FromAssembly(GetType().Assembly) | |
.Where(x => x.Name.EndsWith("ViewModel")) | |
.Configure(x => x.LifeStyle.Is(LifestyleType.Transient))); | |
} | |
} | |
// If you don't already have a ForEach extension method in your project here you go: | |
public static class ForEachExtension | |
{ | |
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) | |
{ | |
foreach (T element in source) | |
{ | |
action(element); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks Brian. This is what I was looking for.
Any idea about how the ViewModel release management should be handled?
When I have to show a new window, I am first using Castle's container to resolve the new ViewModel, and then invoking the ShowWindow method of WindowManager to take care of the rest.
But how I can make sure this is released from the container after the window is closed?
Accounting to the document, even though the LifeStyle of view model is set to transient, it's still necessary to invoke Release when the window is closed.
http://docs.castleproject.org/Default.aspx?Page=LifeStyles&NS=Windsor&AspxAutoDetectCookieSupport=1#Transient_5