具有多租户应用程序的自动映射 - 我们如何为每个租户提供自定义映射规则?

Gra*_*ler 2 dependency-injection autofac multi-tenant automapper

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

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

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

Tra*_*lig 5

您的第一步是告诉AutoMapper绑定服务构建的依赖项解析.您可以在MVC中使用以下内容执行此操作:

AutoMapper.Mapper.Configuration.ConstructServicesUsing(
  t => DependencyResolver.Current.GetService(t));
Run Code Online (Sandbox Code Playgroud)

接下来,使用基类或接口构建自定义值解析器等,以便可以注入它们.

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";
  }
}
Run Code Online (Sandbox Code Playgroud)

现在使用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);
Run Code Online (Sandbox Code Playgroud)

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

Mapper.CreateMap<DataModel, ViewModel>()
  .ForMember(d => d.DisplayName,
             opt => opt.ResolveUsing<FormattingResolver>());
Run Code Online (Sandbox Code Playgroud)

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

我有几个自己的应用程序,它工作得很好.