4

我在让 aufotac 注入我的 autopmapper 类型转换器时遇到问题。我尝试了一些不同的方法,但我目前无法使用下面的代码。我最接近找到解决方案的是下面的代码(从http://thoai-nguyen.blogspot.se/2011/10/autofac-automapper-custom-converter-di.html借来的小片段)。他的样本似乎可以 1:1 工作,但无法找到我缺少的东西。像往常一样提取相关位,如果不够,请告诉我。

我的 autofac 引导程序:

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;
        }
    }

我的 Automap 引导程序/初始化程序:

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<,> 和 LongToEntity<> 以及似乎没有帮助的变体。

4

1 回答 1

8

您当前的代码存在三个问题:

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

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

    所以正确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;
    
于 2013-07-21T15:56:25.687 回答