4

I have tried various permutations of this but my current configuration (as it relates to AutoMapper) is like this:

builder.RegisterAssemblyTypes().AssignableTo(typeof(Profile)).As<Profile>();

builder.Register(c => new MapperConfiguration(cfg =>
{
    foreach (var profile in c.Resolve<IEnumerable<Profile>>())
    {
        cfg.AddProfile(profile);
    }
})).AsSelf().SingleInstance();


builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve)).As<IMapper>().InstancePerLifetimeScope();

builder.RegisterType<MappingEngine>().As<IMappingEngine>();

I have a constructor using IMapper mapper, however I continue to get the YSOD:

None of the constructors found with'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'
on type '' can be invoked with the available services and parameters:
 Cannot resolve parameter 'AutoMapper.IMapper mapper' of constructor 
'Void .ctor(...,...,..., AutoMapper.IMapper)'.

This class works perfectly without the automapper reference so I'm certain that the trouble lies with my automapper configuration.

I'm not sure what I'm missing here as I'm very new to both AutoFac and AutoMapper.

Edit:

I've also tried:

builder.Register(c => new MapperConfiguration(cfg =>
{
    cfg.CreateMap<IdentityUser, AspNetUser>().ReverseMap();
})).AsSelf().SingleInstance();

builder.Register(ctx => ctx.Resolve<MapperConfiguration>().CreateMapper()).As<IMapper>();
//I've tried both of these lines separately, neither work
builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve)).As<IMapper>().InstancePerLifetimeScope();

I've also tried manually adding the profiles per the suggestion in the comments

Eonasdan
  • 7,563
  • 8
  • 55
  • 82
  • What happens if you temporarily add your profiles manually instead of using `IEnumerable`? – devuxer Feb 22 '16 at 23:26
  • @devuxer see my update. That doesn't work either :( – Eonasdan Feb 22 '16 at 23:33
  • I think your assembly scanning code might not be quite right, but I tried the rest of your code in a test app, and it works fine. So, something else must be causing the problem. Have you placed a breakpoint at the line where you register your `IMapper` to make sure it's actually getting hit? – devuxer Feb 23 '16 at 00:02
  • Yup, break point hits no problem. Like I said, the rest of my autofac stuff is working. – Eonasdan Feb 23 '16 at 00:04
  • I created an answer so I could show you my test code. Bottom line: your AutoFac code seems to be fine. Something else is wrong. – devuxer Feb 23 '16 at 00:11
  • well here's a perfect picard face palm moment. I started with AM but put it aside for later. The autofac .Build was **before** my AM code. *sigh* – Eonasdan Feb 23 '16 at 00:16

2 Answers2

8

As I mentioned in a comment, your AutoFac code appears to be correct (except for the assembly scanning portion).

I created the following test app, and it does in fact run without any exceptions and puts a 3 into the Output window (as intended):

using System.Diagnostics;
using Autofac;
using AutoMapper;

namespace Sandbox
{
    public partial class App
    {
        public App()
        {
            var builder = new ContainerBuilder();
            builder.Register(
                c => new MapperConfiguration(cfg =>
                {
                    cfg.AddProfile(new TestProfile());
                }))
                .AsSelf()
                .SingleInstance();

            builder.Register(
                c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve))
                .As<IMapper>()
                .InstancePerLifetimeScope();

            builder.RegisterType<MappingEngine>()
                .As<IMappingEngine>();

            builder.RegisterType<Test>().AsSelf();

            var container = builder.Build();
            container.Resolve<Test>();
        }
    }

    public class TestProfile : Profile
    {
        protected override void Configure()
        {
            CreateMap<Source, Destination>();
        }
    }

    public class Test
    {
        public Test(IMapper mapper)
        {
            var source = new Source { Id = 3 };
            var destination = mapper.Map<Destination>(source);
            Debug.Print(destination.Id.ToString());
        }
    }

    public class Source
    {
        public int Id { get; set; }
    }

    public class Destination
    {
        public int Id { get; set; }
    }
}

I would suggest creating a new branch of your app in version control and stripping things out until it works.

devuxer
  • 41,681
  • 47
  • 180
  • 292
  • 1
    While not exactly the answer, I had two regions in Startup, one for autofac and one for automapper. The builder.Build() was hidden and I totally brain farted by not moving it. Your answer to look somewhere other than AutoMapper is what made me realize that. – Eonasdan Feb 23 '16 at 00:19
  • Glad I could in some way help :) – devuxer Feb 23 '16 at 00:19
  • Is there a reason why IMapper is not registered as SingleInstance in your example? – m0s Jun 11 '16 at 00:44
0

This is worked for me...

 builder = new ContainerBuilder();
        builder.Register(
            c => new MapperConfiguration(cfg =>
            {
                cfg.AddProfile(new TestProfile());
            }))
            .AsSelf()
            .SingleInstance();

        builder.Register(
            c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve))
            .As<IMapper>()
            .InstancePerLifetimeScope();

        builder.RegisterType<MappingEngine>()
            .As<IMappingEngine>();

        builder.RegisterType<Test>().AsSelf();

        var container = builder.Build();
        container.Resolve<Test>();