Skip to content

Instantly share code, notes, and snippets.

@bryanhunter
Created August 5, 2011 16:29
Show Gist options
  • Save bryanhunter/1127914 to your computer and use it in GitHub Desktop.
Save bryanhunter/1127914 to your computer and use it in GitHub Desktop.
Castle bootstrapper for Caliburn.Micro
// 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);
}
}
}
@HEskandari
Copy link

HEskandari commented Jan 18, 2012 via email

@markawil
Copy link

Looked through Payroll solution 1 and 2, couldn't compile probably because of lacking DevEx products.

But I noticed you're using what looks like Caliburn and not Caliburn.Micro as your bootstrapping was done in the App.xaml.cs.

I couldn't find where you fire up a new view or UI in the code in the Payroll part 2 solution. That's really all I need to get to, presenting a new window or view.

@HEskandari
Copy link

HEskandari commented Jan 19, 2012 via email

@HEskandari
Copy link

HEskandari commented Jan 21, 2012 via email

@jasonching
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment