Filipsi
Filipsi

Reputation: 69

AutoMapper doesn't work at design time when using Caliburn.Micro

Background

I am building user interface for existing CLI application using WPF and Caliburn.Micro. Since I am provided with a bunch of DTO objects I am using AutoMapper to pass data to models that support PropertyChanged notification (using PropertyChangedBase from Caliburn.Micro).

I setting up AutoMapper inside the Bootstrapper#Configure method like this:

Mapper.Initialize(
    config => config.CreateMap<ModelA, ModelB>()
);

And am using it like this in my ViewModel:

private static ModelA[] source = new[] {
    new ModelA {
        Name = "foo"
    },
    new ModelA {
        Name = "bar"
    }
};

public BindableCollection<ModelB> Items { get; } = new BindableCollection<ModelB>(
    Mapper.Map<ModelA[], IEnumerable<ModelB>>(source)
);

Problem description

The problem is that when I am using Design Time support for Caliburn.Micro, the DataMapper only works when you start up the Visual Studio.

xmlns:vm="clr-namespace:CaliburnAutoMapperBug.ViewModels"
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro.Platform"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:ShellViewModel, IsDesignTimeCreatable=True}"
cal:Bind.AtDesignTime="True">

When you change any value in the ViewModel, the change isn't projected into the designer and after you run the application at last once the designer throws an error (image) and stops rendering, but everything works at run-time.

Image

enter image description here

How to replicate

  1. Clone problem example repository
  2. Open the solution
  3. Open Views/ShellView.xaml in designer
  4. At this point the designer should work fine and show 3 items in StackPanel
  5. Open ViewModels/ShellViewModel.cs
  6. Make any changes to source array (change name, remove or add item)
  7. Run the application, you should see the changes you make
  8. Go back to designer for Views/ShellView.xaml
  9. The designer will show a error at line 10: "Unmapped members were found..."

Upvotes: 1

Views: 632

Answers (1)

Filipsi
Filipsi

Reputation: 69

I haven't solved the problem with design time completely, but switching to instance based AutoMapper configuration as suggested resolved the exception.

protected override void Configure() {
    container = new SimpleContainer();
    container.Singleton<IWindowManager, WindowManager>();
    container.Singleton<IEventAggregator, EventAggregator>();
    container.PerRequest<IShell, ShellViewModel>();

    MapperConfiguration config = new MapperConfiguration(cfg => {
        cfg.CreateMap<Core.ProjectDto, Models.Panel.Project>();
    });

    container.RegisterInstance(
        typeof(IMapper),
        "automapper",
        config.CreateMapper()
    );
}

Upvotes: 2

Related Questions