无法在Autofac中注册并添加automapper配置文件

 杨斜2602934873 发布于 2023-02-12 16:02

我有一个多租户Web应用程序,它有多个模块.我使用autofac作为IOC和Automapper来映射我的模型和实体.在下面的代码中,我能够将UserAuthenticationMapper配置文件添加到automapper,但无法添加CustomerDataMapper配置文件.Autofac仅向自动化MappingEngine添加一个映射器配置文件,并忽略其余部分.我在做什么错了?

这是我的UserAuthentication模块:

 public class UserAuthenticationModule: Autofac.Module
 {
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType().As();

        builder.Register(ctx =>
        {
            var configStore = new ConfigurationStore
           (new TypeMapFactory(),  MapperRegistry.AllMappers());
            configStore.AddProfile();
            return configStore;
        })
        .AsImplementedInterfaces()
        .SingleInstance();

        var assembly = Assembly.GetExecutingAssembly();
        builder.RegisterAssemblyTypes(assembly)
               .Where(t => t.Name.EndsWith("Service"))
               .AsImplementedInterfaces()
               .SingleInstance();
      }
  }

CustomerData Modue:

  public class CustomerDataModule : Autofac.Module
  {
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType()
            .As()
            .InstancePerDependency();

        builder.RegisterType().As();

        builder.Register(ctx =>
            {
                var configStore = new ConfigurationStore
                (new TypeMapFactory(), MapperRegistry.AllMappers());
                configStore.AddProfile();
                return configStore;
            })
               .AsImplementedInterfaces()
               .SingleInstance();
      }
   }

这里有一些额外的代码来说明我如何在Global.asax中加载这些模块

    static IContainerProvider _containerProvider;

    public IContainerProvider ContainerProvider
    {
        get { return _containerProvider; }
    }

    void Application_Start(object sender, EventArgs e)
    {
        RouteTable.Routes.MapHttpRoute(
             name: "ActionApi",
             routeTemplate: "api/{controller}/{action}"
         );

        RouteTable.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = System.Web.Http.RouteParameter.Optional }
        );
      var builder = new ContainerBuilder();
      builder.RegisterModule();
      builder.RegisterModule();
      _containerProvider = new ContainerProvider(builder.Build());
     }

错误:

AutoMapper.dll中出现"AutoMapper.AutoMapperMappingException"类型的异常,但未在用户代码中处理缺少类型映射配置或不支持的映射.\ r \n\r \nMapping类型:\ r \n用户 - > UserModel

1 个回答
  • 我猜你遇到的问题是你正在注册两个ConfigurationStore实例,MappingEngine只有一个作为构造函数参数.

    当你在Autofac中注册多个东西时,它就是"最后的胜利".所以,当你解决一个MappingEngine它会挑这样的构造:

    public MappingEngine(IConfigurationProvider configurationProvider)
    

    这只需要一个配置提供程序(ConfigurationStoreimplements IConfigurationProvider),所以你只能获得一个.这意味着它相当于:

    container.Resolve<IConfigurationProvider>();
    

    你只会得到一个.如果您需要解决所有这些问题,则需要解决IEnumerable<IConfigurationProvider>来自Autofac的问题,例如:

    container.Resolve<IEnumerable<IConfigurationProvider>>();
    

    但这不会解决你的问题,它只描述了我认为正在发生的事情.

    你需要做什么才能完成你想做的事情就是把事情搞得一团糟.不是ConfigurationStore在每个模块中注册,而是仅注册配置文件.像这样(缩短了可读性):

    public class CustomerDataModule : Autofac.Module
    {
      protected override void Load(ContainerBuilder builder)
      {
        builder.RegisterType<CustomerDataMapperProfile>().As<Profile>();
      }
    }
    
    public class UserAuthenticationModule : Autofac.Module
    {
      protected override void Load(ContainerBuilder builder)
      {
        builder.RegisterType<UserAuthenticationMapperProfile>().As<Profile>();
      }
    }
    

    然后,您需要从模块中分解常见的AutoMapper注册.你不想双重注册.创建一个新模块,用于处理注册映射引擎,并对配置文件进行一些动态解析.

    public class AutoMapperModule : Autofac.Module
    {
      protected override void Load(ContainerBuilder builder)
      {
        // Register the common thing once, not in each module.
        builder.RegisterType<MappingEngine>().As<IMappingEngine>();
    
        // Here's where you dynamically get all the registered profiles
        // and add them at the same time to the config store.
        builder.Register(ctx =>
          {
            var profiles = ctx.Resolve<IEnumerable<Profile>>();
            var configStore = new ConfigurationStore
                (new TypeMapFactory(), MapperRegistry.AllMappers());
            foreach(var profile in profiles)
            {
              configStore.AddProfile(profile);
            }
            return configStore;
          })
          .AsImplementedInterfaces()
          .SingleInstance();
      }
    }
    

    确保注册容器中的所有模块:

     var builder = new ContainerBuilder();
     builder.RegisterModule<UserAuthenticationModule>();
     builder.RegisterModule<CustomerDataModule>();
     builder.RegisterModule<AutoMapperModule>();
     _containerProvider = new ContainerProvider(builder.Build());
    

    现在,您应该在解决时注册所有配置文件IMappingEngine.

    2023-02-12 16:06 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有