samedi 16 mai 2015

Bootstrapper design pattern using Caliburn.Micro MVVM framework with IoC-container

The WPF application uses Caliburn.Micro as MVVM framework. CM has it's built in IoC-Container named SimpleContainer, I replaced it with Castle.Windsor container. (But container type does not matter here I guess.) CM uses a Bootstrapper.Configure() method where container can be configured. After that Bootstrapper.OnStartup() method starts application displaying a View for root ViewModel. So container configures before first View appears. In my case container configuration a pretty complex and may cause errors. For example I want to deserialize some XML files from app directory to objects and register them as components in container. So I want to get a SplashScreen to see container configuring progress, and then if all OK, splash disappears, container resolves root item and application starts as expected. If not - problem shown on splashscreen. I can't get in mind how to get a SplashScreenView (binded to SplashScreenViewModel) before I get a configured container. So application divides on "before" and "after" container. How can that issue can be solved? Is there any patterns? Is it OK to partly configure container in Configure and partly somewhere else, after it Resolved some components? Or maybe there is a practic to use container instance "inside" components resolved by another container instance? Thanks.

public class CastleModernUIBootstrapper : BootstrapperBase
    {
        private WindsorContainer _container;
        public CastleModernUIBootstrapper()
        {
            Initialize();
        }
        protected override void Configure()
        {
            _container = new WindsorContainer();
            // here components are registered. 
            // I want perform complex container configuration here,
            // but I can't vizualize what happens here.
            _container.Register(Component.For<LoadingSplashScreenViewModel>());
            // ...
        }
        // ...
        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            // after we resolving first element from container
            DisplayRootViewFor<LoadingSplashScreenViewModel>();
        }
    }

Aucun commentaire:

Enregistrer un commentaire