CompositionHelper is not configured. CompositionHelper.Configure must be called before any other public method.

Oct 16, 2011 at 9:11 PM

"CompositionHelper is not configured. CompositionHelper.Configure must be called before any other public method."

I keep getting this error during design.  Application runs fine, just this error in the designer. 

I attempted to debug the design time code and it shows that "CompositionHelper.IsConfigured" is never set to true causing the exception to be thrown.  

Any help would be appreciated.

Coordinator
Oct 16, 2011 at 11:32 PM

You can't use the CompositionHelper at design time. CompositionHelper.IsConfigured always returns false at design time. This is because MEF doesn't really work in Blend and VS. At design time, you have to manually inject all your dependencies into the respective constructors as you new up your VMs and it's dependencies in the ViewModelLocator. You'll have to track down in your code, where you are trying to resolve a dependency through the CompositionHelper and change it so that you can constructor-inject that dependency at design time. The golden rule for IoC is to not use an IoC container at design time and in your unit tests.

 

Oct 21, 2011 at 10:46 PM

Thanks for the reply.  BTW,  I just moved my entire project to Devforce and CM.  Love it!!!!  

Not sure if I understand fully what you are saying.  I am not specifically using the CompositionHelper that I know of.  

Are you saying I have to implemenet the ViewModelLocator?  I remove the locator from my App.xaml.  The error comes from the AppBootstrapper.  I guess I am not sure what I need to change to have the error go away.  

It's a pain to have the designer always error out.

          
    <!--          <dts:ViewModelLocator x:Key="ViewModelLocator" />-->
          <Shell:AppBootstrapper x:Key="bootstrapper" />

 

 

Coordinator
Oct 22, 2011 at 11:34 PM

I'm glad you like it. If you want to use design time data then you need to implement the ViewModelLocator, but only then. Sounds like you have something in the bootstrapper that is causing the issue. Can you post your bootstrapper, so I can take a look?

Oct 23, 2011 at 12:12 AM

Line 34 is where the error occurs which is the start of the contructor.

namespace Prime.WPF.VVM.Shell
{
    using System;
    using System.ComponentModel.Composition.Hosting;
    using System.Linq;
    using System.Reflection;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Media.Imaging;
    using System.Windows.Threading;
    using Caliburn.Micro;
    using Caliburn.Micro.Extensions;
    using Caliburn.Micro.Logging;
    using DataAccess;
    using DataAccess.DataObjects;
    using Framework.Converters;
    using IdeaBlade.Core.Composition;
    using IdeaBlade.Core.Wcf.Extensions;
    using IdeaBlade.EntityModel;
    using Ionic.Zlib;
    using Library.Email;
    using Library.Events;
    using Library.General;
    using Telerik.Windows.Controls;
    
    using BooleanToVisibilityConverter = Telerik.Windows.Controls.BooleanToVisibilityConverter;

    public class AppBootstrapper : FrameworkBootstrapper<ShellViewModel, PrimeEntities>

    {
        private readonly bool DoHandle;

        public AppBootstrapper()
        {
            DoHandle = true;

           

            Application.Current.DispatcherUnhandledException += CurrentDispatcherUnhandledException;


            //LogManager.GetLog = type => new LocalLogger(type);

            if (!Execute.InDesignMode)
            {

                if (!CanConnect())
                {
                    MessageBox.Show("Unable to connect to application services.  Please try again later.");
                    Application.Current.Shutdown();
                }

//
//                //LogManager.GetLog = type => new LocalLogger(type);
//                ILog log = LogManager.GetLog(typeof (AppBootstrapper));
//                log.Info("AppBootstrapper constructor");
            }
        }

        private void CurrentDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            var exception = new RepositoryException(e.Exception);

            if ((e.Exception is EntityServerConnectionException || e.Exception is EntityServerException) && exception.IsConnectionError)
            {
                e.Handled = true;
                return;
            }


            e.Handled = DoHandle;

            if (e.Exception == null) return;

            ExceptionData exceptionData = e.Exception.ToExceptionData();
            var emailService = IoC.Get<IEmailServiceWeb>();

            if (emailService != null && exceptionData != null) emailService.SendExceptionEmail(exceptionData);
        }
       
        public bool CanConnect()
        {
            CommunicationSettings.Default.CompressionLevel = CompressionLevel.Level9;

            CompositionHost.SearchPatterns.Clear();
            CompositionHost.SearchPatterns.Add("Prime.DataAccess.dll");

            try
            {
                var em = new PrimeEntities();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
       
        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            base.OnStartup(sender, e);

           var iconUri = new Uri("pack://application:,,,/Assets/Graphics/Bank.ico", UriKind.RelativeOrAbsolute);
           Application.MainWindow.Icon = BitmapFrame.Create(iconUri);
        }
       
        protected override void InitializeCompositionBatch(CompositionBatch batch)
        {
            base.InitializeCompositionBatch(batch);

//#if DEBUG
//         // For the Debug build, use the fake store EntityManagerProvider
//
//
////         batch.AddExportedValue<IEntityManagerProvider<PrimeEntities>>(new DevelopmentEntityManagerProvider(new SampleDataProvider(new SampleDataLoader())));
//         //batch.AddExportedValue<IEntityManagerProvider<PrimeEntities>>(new EntityManagerProvider());
//
//#else
//   // For the Release build, use the production EntityManagerProvider
//            batch.AddExportedValue<IEntityManagerProvider<PrimeEntities>>(new EntityManagerProvider());
//#endif

            //batch.AddPart(new EntityManagerProvider());

            ConventionManager.ApplyUpdateSourceTrigger = (bindableProperty, element, binding, info) =>
                                                             {
//             binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                                                             };

            ConventionManager
                .ApplyValueConverter = (binding, bindableProperty, property)
                                       =>
                                           {
                                               if (bindableProperty == UIElement.VisibilityProperty && typeof (bool).IsAssignableFrom(property.PropertyType))
                                                   binding.Converter = new BooleanToVisibilityConverter();

                                               if (bindableProperty == TextBox.TextProperty &&
                                                   (typeof (int).IsAssignableFrom(property.PropertyType) || typeof (int?).IsAssignableFrom(property.PropertyType)))
                                                   binding.Converter = new TextBoxToIntegerConverter();

                                               if (bindableProperty == TextBox.TextProperty &&
                                                   (typeof (decimal).IsAssignableFrom(property.PropertyType) || typeof (decimal?).IsAssignableFrom(property.PropertyType)))
                                                   binding.Converter = new TextBoxToDecimalConverter();
                                           };


            ConventionManager.AddElementConvention<RadBusyIndicator>(RadBusyIndicator.IsBusyProperty, "IsBusy", "Loaded");

            ConventionManager.AddElementConvention<RadDatePicker>(RadDatePicker.SelectedValueProperty, "SelectedValue", "SelectionChanged");

            ConventionManager.AddElementConvention<RadGridView>(DataControl.ItemsSourceProperty, "SelectedItem", "RowActivated")
                .ApplyBinding = (viewModelType, path, property, element, convention) =>
                                    {
                                        if (!ConventionManager.SetBinding(viewModelType, path, property, element, convention)) return false;
                                        if (ConventionManager.HasBinding(element, DataControl.SelectedItemProperty)) return true;
                                        int index = path.LastIndexOf('.');
                                        index = index == -1 ? 0 : index + 1;
                                        string baseName = path.Substring(index);
                                        foreach (string selectionPath in
                                            from potentialName in ConventionManager.DerivePotentialSelectionNames(baseName)
                                            where viewModelType.GetProperty(potentialName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) != null
                                            select path.Replace(baseName, potentialName))
                                        {
                                            BindingOperations.SetBinding(element, DataControl.SelectedItemProperty, new Binding(selectionPath) {Mode = BindingMode.TwoWay});
                                        }
                                        return true;
                                    };


//            ConventionManager.AddElementConvention<DataGridControl>(DataControl.ItemsSourceProperty, "SelectedItem", "MouseDoubleClick")
//                .ApplyBinding = (viewModelType, path, property, element, convention) =>
//                                    {
//                                        if (!ConventionManager.SetBinding(viewModelType, path, property, element, convention)) return false;
//                                        if (ConventionManager.HasBinding(element, DataControl.SelectedItemProperty)) return true;
//                                        int index = path.LastIndexOf('.');
//                                        index = index == -1 ? 0 : index + 1;
//                                        string baseName = path.Substring(index);
//                                        foreach (string selectionPath in
//                                            from potentialName in ConventionManager.DerivePotentialSelectionNames(baseName)
//                                            where viewModelType.GetProperty(potentialName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) != null
//                                            select path.Replace(baseName, potentialName))
//                                        {
//                                            BindingOperations.SetBinding(element, DataControl.SelectedItemProperty, new Binding(selectionPath) {Mode = BindingMode.TwoWay});
//                                        }
//                                        return true;
//                                    };
        }
    }
}
Coordinator
Oct 23, 2011 at 8:44 AM

I'm not seeing anything specifically for design time. There must be something else going on outside of the Bootstrapper, but I saw a couple of things that ring my alarm bells.

  1. All that stuff you are doing in the constructor does not belong in a constructor. Should probably go in OnStartup.
  2. Additional configuration such as add conventions should go in the Configure method.
  3. Certain things don't work if you leave the framework out of the CompositionHost.SearchPatterns. If you mess with the SearchPatterns, make sure you add IB.Application.Framework.Desktop.dll or IB.Application.Framework.SL.dll in case of Silverlight.

I'm gonna have to see the call stack at design time when the error occurs. You'll have to debug what's going on. The easiest way to debug design time issues is to attach the Debugger to Blend.

 

Coordinator
Oct 23, 2011 at 8:46 AM

And I forgot. The bootstrapper already has a method you can override for unhandled exceptions. It's called OnUnhandledException().

Oct 24, 2011 at 12:02 AM
Edited Oct 24, 2011 at 2:22 AM

Thought it worked.  But it doesn't.  I removed everything out of the bootstapper.  Seem new bootstrapper below.

Breaks on "base.Configure();"

Debug Stack

CompositionHelper is not configured. CompositionHelper.Configure must be called before any other public method.   at IdeaBlade.Application.Framework.Core.Composition.CompositionHelper.CheckIfConfigured() in c:\Source\Projects\CashCall\VS2010\V3\CodePlex\devforcecaliburn\IB.Application.Framework.Core\Composition\CompositionHelper.cs:line 257   at Caliburn.Micro.Extensions.FrameworkBootstrapper`2.BuildUp(Object instance) in c:\Source\Projects\CashCall\VS2010\V3\CodePlex\devforcecaliburn\Caliburn.Micro.Extensions\FrameworkBootstrapper.cs:line 159   at Caliburn.Micro.Extensions.FrameworkBootstrapper`2.RefreshCaliburnAssemblySource(Object sender, EventArgs e) in c:\Source\Projects\CashCall\VS2010\V3\CodePlex\devforcecaliburn\Caliburn.Micro.Extensions\FrameworkBootstrapper.cs:line 135   at Caliburn.Micro.Extensions.FrameworkBootstrapper`2.Configure() in c:\Source\Projects\CashCall\VS2010\V3\CodePlex\devforcecaliburn\Caliburn.Micro.Extensions\FrameworkBootstrapper.cs:line 100   at Prime.WPF.VVM.Shell.AppBootstrapper.Configure() in C:\Source\Projects\CashCall\VS2010\V3\Apps\Prime.WPF\VVM\Shell\AppBootstrapper.cs:line 112   at Caliburn.Micro.Bootstrapper.StartDesignTime() in c:\Source\Projects\CashCall\VS2010\V3\CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\Bootstrapper.cs:line 48   at Caliburn.Micro.Extensions.FrameworkBootstrapper`2..ctor()   at Prime.WPF.VVM.Shell.AppBootstrapper..ctor()

 

 

namespace Prime.WPF.VVM.Shell
{
   using System;
   using System.ComponentModel.Composition.Hosting;
   using System.Linq;
   using System.Reflection;
   using System.Windows;
   using System.Windows.Controls;
   using System.Windows.Data;
   using System.Windows.Media.Imaging;
   using System.Windows.Threading;
   using Caliburn.Micro;
   using Caliburn.Micro.Extensions;
   using DataAccess;
   using DataAccess.DataObjects;
   using Framework.Converters;
   using IdeaBlade.Core.Composition;
   using IdeaBlade.Core.Wcf.Extensions;
   using IdeaBlade.EntityModel;
   using Ionic.Zlib;
   using Library.Email;
   using Library.Events;
   using Library.General;
   using Telerik.Windows.Controls;
   using BooleanToVisibilityConverter = Telerik.Windows.Controls.BooleanToVisibilityConverter;

   public class AppBootstrapper : FrameworkBootstrapper<ShellViewModel, PrimeEntities>

   {
      protected bool DoHandle;

      

      protected override void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
      {
         base.OnUnhandledException(sender, e);


//         var exception = new RepositoryException(e.Exception);
//
//         if ((e.Exception is EntityServerConnectionException || e.Exception is EntityServerException) && exception.IsConnectionError)
//         {
//            e.Handled = true;
//            return;
//         }
//
//
//         e.Handled = DoHandle;
//
//         if (e.Exception == null) return;
//
//         ExceptionData exceptionData = e.Exception.ToExceptionData();
//         var emailService = IoC.Get<IEmailServiceWeb>();
//
//         if (emailService != null && exceptionData != null) emailService.SendExceptionEmail(exceptionData);
      }

      public bool CanConnect()
      {
         CommunicationSettings.Default.CompressionLevel = CompressionLevel.Level9;

//         CompositionHost.SearchPatterns.Clear();
//         CompositionHost.SearchPatterns.Add("Prime.DataAccess.dll");

         try
         {
            var em = new PrimeEntities();
            return true;
         }
         catch (Exception)
         {
            return false;
         }
      }

      protected override void OnStartup(object sender, StartupEventArgs e)
      {
         base.OnStartup(sender, e);
         
         DoHandle = true;


         //LogManager.GetLog = type => new LocalLogger(type);
//
//         if (!Execute.InDesignMode)
//         {
//            if (!CanConnect())
//            {
//               MessageBox.Show("Unable to connect to application services.  Please try again later.");
//               Application.Current.Shutdown();
//            }
//
//            var iconUri = new Uri("pack://application:,,,/Assets/Graphics/Bank.ico", UriKind.RelativeOrAbsolute);
//            Application.MainWindow.Icon = BitmapFrame.Create(iconUri);
//
//            //
//            //                //LogManager.GetLog = type => new LocalLogger(type);
//            //                ILog log = LogManager.GetLog(typeof (AppBootstrapper));
//            //                log.Info("AppBootstrapper constructor");
//         }




         

      }

      protected override void Configure()
      {

      base.Configure();

//      ConventionManager.ApplyUpdateSourceTrigger = (bindableProperty, element, binding, info) =>
//      {
//         //             binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
//      };
//
//      ConventionManager
//         .ApplyValueConverter = (binding, bindableProperty, property)
//                                =>
//         {
//            if (bindableProperty == UIElement.VisibilityProperty && typeof(bool).IsAssignableFrom(property.PropertyType))
//               binding.Converter = new BooleanToVisibilityConverter();
//
//            if (bindableProperty == TextBox.TextProperty &&
//                (typeof(int).IsAssignableFrom(property.PropertyType) || typeof(int?).IsAssignableFrom(property.PropertyType)))
//               binding.Converter = new TextBoxToIntegerConverter();
//
//            if (bindableProperty == TextBox.TextProperty &&
//                (typeof(decimal).IsAssignableFrom(property.PropertyType) || typeof(decimal?).IsAssignableFrom(property.PropertyType)))
//               binding.Converter = new TextBoxToDecimalConverter();
//         };
//
//
//      ConventionManager.AddElementConvention<RadBusyIndicator>(RadBusyIndicator.IsBusyProperty, "IsBusy", "Loaded");
//
//      ConventionManager.AddElementConvention<RadDatePicker>(RadDatePicker.SelectedValueProperty, "SelectedValue", "SelectionChanged");
//
//      ConventionManager.AddElementConvention<RadGridView>(DataControl.ItemsSourceProperty, "SelectedItem", "RowActivated")
//         .ApplyBinding = (viewModelType, path, property, element, convention) =>
//         {
//            if (!ConventionManager.SetBinding(viewModelType, path, property, element, convention)) return false;
//            if (ConventionManager.HasBinding(element, DataControl.SelectedItemProperty)) return true;
//            int index = path.LastIndexOf('.');
//            index = index == -1 ? 0 : index + 1;
//            string baseName = path.Substring(index);
//            foreach (var selectionPath in
//               from potentialName in ConventionManager.DerivePotentialSelectionNames(baseName)
//               where viewModelType.GetProperty(potentialName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) != null
//               select path.Replace(baseName, potentialName))
//            {
//               BindingOperations.SetBinding(element, DataControl.SelectedItemProperty, new Binding(selectionPath) { Mode = BindingMode.TwoWay });
//            }
//            return true;
//         };


       


      }

      protected override void InitializeCompositionBatch(CompositionBatch batch)
      {
         base.InitializeCompositionBatch(batch);
      }
   }
}
Coordinator
Oct 24, 2011 at 5:21 AM

Ah, looks like you are running an old build. I made a change on Oct 4, that should fix this. Get the latest code and let me know if you are still having trouble.

Oct 24, 2011 at 9:59 PM

That seemed to do it.

 

Thanks!