4

我目前正在试验 AutoMapper(最新的 .NET 3.5 版本)。要使 AutoMapper 工作,您必须为其提供有关如何从一个对象映射到另一个对象的配置详细信息。

Mapper.CreateMap<ContactDTO, Contact>();
Mapper.CreateMap<Contact, ContactDTO>();

您应该在应用程序、服务、网站启动时执行此操作。(使用 global.asax 等)

问题是,我在 GAC 的 DLL 中使用 Automapper 将 LINQ2SQL 对象映射到它们的 BO 对应对象。为了避免一直指定 .CreateMap<> 详细信息,我想要映射 2 对象,如果可能的话,我可以在哪里指定此配置

4

1 回答 1

0

我相信解决方案就在 AutoMapper 本身。

使用 AutoMapper Profiles 并在启动时注册它们。

如果您的配置文件不需要任何依赖项,则下面的示例甚至不需要 IOC 容器。

/// <summary>
///     Helper class for scanning assemblies and automatically adding AutoMapper.Profile
///     implementations to the AutoMapper Configuration.
/// </summary>
public static class AutoProfiler
{
    public static void RegisterReferencedProfiles()
    {
        AppDomain.CurrentDomain
            .GetReferencedTypes()
            .Where(type => type != typeof(Profile) 
              && typeof(Profile).IsAssignableFrom(type) 
              && !type.IsAbstract)
            .ForEach(type => Mapper.Configuration.AddProfile(
              (Profile)Activator.CreateInstance(type)));
    }
}

他们只是像这个例子一样实现配置文件:

public class ContactMappingProfile : Profile
{
    protected override void Configure()
    {
        this.CreateMap<Contact, ContactDTO>();
        this.CreateMap<ContactDTO, Contact>();
    }
}

但是,如果您的配置文件有需要解决的依赖关系,您可以为 AutoMapper 创建一个抽象,并在注册抽象之前注册所有配置文件 - IObjectMapper - 像这样的单例:

public class AutoMapperModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        base.Load(builder);

        // register all profiles in container
        AppDomain.CurrentDomain
            .GetReferencedTypes()
            .Where(type => type != typeof(Profile)
              && typeof(Profile).IsAssignableFrom(type) 
              && !type.IsAbstract)
            .ForEach(type => builder
                .RegisterType(type)
                .As<Profile>()
                .PropertiesAutowired());

        // register mapper
        builder
            .Register(
                context =>
                {
                    // register all profiles in AutoMapper
                    context
                        .Resolve<IEnumerable<Profile>>()
                        .ForEach(Mapper.Configuration.AddProfile);
                    // register object mapper implementation
                    return new AutoMapperObjectMapper();
                })
            .As<IObjectMapper>()
            .SingleInstance()
            .AutoActivate();
    }
}

由于我抽象了该领域中的所有技术,这对我来说似乎是最好的方法。

现在去编码,伙计,gooooo!

PS-代码可能正在使用一些帮助程序和扩展,但它的核心内容就在那里。

于 2015-02-08T16:03:46.130 回答