【问题标题】:Automapper with Multi-Tenant Application - How can we supply custom mapping rule per tenant?Automapper with Multi-Tenant Application - 我们如何为每个租户提供自定义映射规则?
【发布时间】:2013-06-26 13:35:34
【问题描述】:

我们有一个多租户应用程序 - 它基于使用 AutoFac 多租户插件。我们还使用 AutoMapper 进行域到 ViewModel 的映射。

我们现在已经要求客户为其 ViewModel 属性设置不同的映射规则/格式。例如某个客户想要一个以特定值等为前缀的字段。另一个客户想要一个值替换为默认值(如果不存在值)。无论如何,这可以通过 AutoMapper 来完成。该配置似乎为每个应用程序域配置一次,每个人都获得相同的映射。

是否有配置默认映射,然后为每个租户覆盖?关于我们如何处理这个问题的任何想法?理想情况下,使用 DI 从租户子容器中提取一些额外的映射。

【问题讨论】:

    标签: dependency-injection automapper autofac multi-tenant


    【解决方案1】:

    您的第一步是告诉 AutoMapper 绑定到依赖项解析以进行服务构建。你可以在 MVC 中这样做:

    AutoMapper.Mapper.Configuration.ConstructServicesUsing(
      t => DependencyResolver.Current.GetService(t));
    

    接下来,使用基类或接口构造您的custom value resolvers 等,以便可以注入它们。

    public abstract class FormattingResolver : IValueResolver
    {
      public ResolutionResult Resolve(ResolutionResult source)
      {
        return source.New(this.Format(source.Value.ToString()));
      }
    
      public abstract string Format(string input);
    }
    
    public class DefaultFormatter : FormattingResolver
    {
      public override string Format(string input)
      {
        return input + "Default";
      }
    }
    
    public class Tenant1Formatter : FormattingResolver
    {
      public override string Format(string input)
      {
        return input + "Tenant 1";
      }
    }
    

    现在使用 Autofac 和多租户支持注册这些值解析器。

    var builder = new ContainerBuilder();
    
    // Register the default in the app container
    builder.RegisterType<DefaultFormatter>().As<FormattingResolver>();
    
    var container = builder.Build();
    var mtc = new MultitenantContainer(new TenantIdStrategy(), container);
    
    // Register the tenant override
    mtc.ConfigureTenant(
      'Tenant1',
      b => b.RegisterType<Tenant1Formatter>().As<FormattingResolver>());
    
    // Make sure the dependency resolver is multitenant
    var resolver = new AutofacDependencyResolver(mtc);
    DependencyResolver.SetResolver(resolver);
    

    注册 AutoMapper 映射时,请确保使用基类,而不是自定义值解析器的特定类。

    Mapper.CreateMap<DataModel, ViewModel>()
      .ForMember(d => d.DisplayName,
                 opt => opt.ResolveUsing<FormattingResolver>());
    

    现在当 AutoMapper 执行映射操作时,它将通过调用 DependencyResolver.Current.GetService 获取自定义值解析器,并且 Autofac 多租户容器将为租户返回适当的解析器。映射将使用特定租户的自定义值解析器,这意味着覆盖格式将按预期进行。

    我在我自己的几个应用程序中都有这个功能,效果很好。

    【讨论】:

      猜你喜欢
      • 2015-10-13
      • 2017-02-17
      • 1970-01-01
      • 2015-10-20
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多