Automapper& Autofac typeconverter - 没有默认构造函数

时间:2013-07-21 12:21:23

标签: c# automapper autofac

我有问题让aufotac注入我的autopmapper typeconverters。我尝试了一些不同的方法,但我目前使用下面的代码。最接近寻求解决方案的是下面的代码(借用http://thoai-nguyen.blogspot.se/2011/10/autofac-automapper-custom-converter-di.html中的小位)。他的样本似乎以1:1的方式工作,但还没能找到我失踪的东西。像往常一样提取相关位,让我知道它是否不足。

我的autofac bootstrapper:

public class AutoFacInitializer
    {
        public static void Initialize()
        {
            //Mvc
            var MvcContainer = BuildMvcContainer();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(MvcContainer));

            //Web API
            var ApiContainer = BuildApiContainer();
            var ApiResolver = new AutofacWebApiDependencyResolver(ApiContainer);
            GlobalConfiguration.Configuration.DependencyResolver = ApiResolver;
        }

        private static IContainer BuildApiContainer()
        {
            var builder = new ContainerBuilder();
            var assembly = Assembly.GetExecutingAssembly();
            builder.RegisterApiControllers(assembly);
            return BuildSharedDependencies(builder, assembly);
        }

        private static IContainer BuildMvcContainer()
        {
            var builder = new ContainerBuilder();
            var assembly = typeof (MvcApplication).Assembly;
            builder.RegisterControllers(assembly);
            builder.RegisterFilterProvider();
            return BuildSharedDependencies(builder, assembly);
        }

        private static IContainer BuildSharedDependencies(ContainerBuilder builder, Assembly assembly)
        {
            //----Build and return container----
            IContainer container = null;

            //Automapper
            builder.RegisterAssemblyTypes(assembly).AsClosedTypesOf(typeof(ITypeConverter<,>)).AsSelf();
            AutoMapperInitializer.Initialize(container);
            builder.RegisterAssemblyTypes(assembly).Where(t => typeof(IStartable).IsAssignableFrom(t)).As<IStartable>().SingleInstance();

            //Modules
            builder.RegisterModule(new AutofacWebTypesModule());
            builder.RegisterModule(new NLogLoggerAutofacModule());

            //Automapper dependencies
            builder.Register(x => Mapper.Engine).As<IMappingEngine>().SingleInstance();

            //Services, repos etc
            builder.RegisterGeneric(typeof(SqlRepository<>)).As(typeof(IRepository<>)).InstancePerDependency();

            container = builder.Build();
            return container;
        }
    }

My Automap bootstrapper / initializer:

namespace Supportweb.Web.App_Start
{
    public class AutoMapperInitializer
    {
        public static void Initialize(IContainer container)
        {
            Mapper.Initialize(map =>
            {
                map.CreateMap<long?, EntityToConvertTo>().ConvertUsing<LongToEntity<NavigationFolder>>();

                map.ConstructServicesUsing(t => container.Resolve(t)); 
            });
            Mapper.AssertConfigurationIsValid();
        }
    }
}

我试图开始工作的转换器:

public class LongToEntity<T> : ITypeConverter<long?, T>
    {
        private readonly IRepository<T> _repo;

        public LongToEntity(IRepository<T> repo)
        {
            _repo = repo;
        }

        public T Convert(ResolutionContext context) 
        {
            long id = 0;
            if (context.SourceValue != null)
                id = (long)context.SourceValue;
            return _repo.Get(id);
        }
    }

除转换器外,所有映射都能正常工作。该错误似乎表明我缺少ioc参考但我已经尝试但提到的ITypeConverter&lt;,&gt;和LongToEntity&lt;&gt;并没有看到帮助的变化。

1 个答案:

答案 0 :(得分:6)

您当前的代码有三个问题:

  1. 您需要在注册任何映射之前致电ConstructServicesUsing ,如链接文章中所述:

      

    棘手的是我们需要在注册mapper类之前调用​​该方法。

    所以正确的Mapper.Initialize如下:

       
    Mapper.Initialize(map =>
            {
                map.ConstructServicesUsing(t => container.Resolve(t));  
    
                map.CreateMap<long?, EntityToConvertTo>()
                    .ConvertUsing<LongToEntity<NavigationFolder>>();
            });
    
  2. 由于您的LongToEntity<T>是开放式通用,因此您无法使用AsClosedTypesOf,但您还需要使用RegisterGeneric进行注册:

    因此请更改您的ITypeConverter<,>注册:

       
     builder.RegisterAssemblyTypes(assembly)
            .AsClosedTypesOf(typeof(ITypeConverter<,>)).AsSelf();
    

    使用RegisterGeneric方法:

      
     builder.RegisterGeneric(typeof(LongToEntity<>)).AsSelf();
    
  3. 因为您已将Automapper初始化移动到单独的方法AutoMapperInitializer.Initialize中,所以您无法使用文章中的clojure技巧,因此您需要在创建之后将其称为容器:

      
     container = builder.Build();
     AutoMapperInitializer.Initialize(container);
     return container;