在独立的可重用库中,在AutoMapper中创建地图的推荐方法是什么?

时间:2012-06-28 04:01:51

标签: c# automapper appdomain

我正在整理一个.Net 4库,该库旨在作为独立程序集进行分发。该库的一部分执行一些特殊的Web服务调用,我计划在其中将预计版本返回给库的使用者。 Web服务响应表示与库的消费者实际获得的内容之间需要进行大量的映射。我希望利用AutoMapper来完成这项任务;通常情况下,惯例将能够为我处理很多无聊的从右到左的映射代码。

因此,例如,我的库可能会公开看起来有点像的代码:

public Widget GetWidget(Guid id)
{
    // Get server representation
    ServerWidget serverWidget = this.Request<ServerWidget>(id);

    // Map to client representation
    Widget clientWidget = Mapper.Map<ServerWidget, Widget>(serverWidget);

    return clientWidget;
}

在代码的其他地方我显然需要调用(加上映射的任何自定义配置):

Mapper.CreateMap<ServerWidget, Widget>();

Per design guidelines of AutoMapper,这应该只针对每个AppDomain执行一次(因为这是一项昂贵的操作)。由于这个库可以在任何可能的环境中使用(ASP.NET,WinForms应用程序,WPF应用程序,单元测试运行程序等),如何在这种情况下正确设置映射?

显然,我的代码可能会暴露某种方法让客户端调用“初始化东西”(在这种情况下为映射器)并假设他们确实进行了调用,并且在应用程序启动过程中的正确时间,但是这对于强加给图书馆的消费者来说似乎是一个非常蹩脚的要求。

任何人对我有任何建议和/或可以指向GitHub,Codeplex等开源项目已经做过这样的事情吗?

2 个答案:

答案 0 :(得分:2)

如何在您的库中使用静态IsMappingInitialised方法,在执行这样的映射之前检查它,这是线程安全的:

private static readonly object MappingLock = new object();
private static bool _ready = false;

public static bool IsMappingInitialised()
{
    if (!_ready)
    {
        lock (MappingLock)
        {
            if (!_ready)
            {
                Mapper.CreateMap<ServerWidget, Widget>();
                _ready = true;
            }
        }
    }

    return _ready;
}

通过这种方式,您无需依赖消费者进行初始化。

答案 1 :(得分:2)

您还可以使用.Net的static constructor功能。 在类中添加静态构造函数并添加地图的创建。您不需要任何锁定,因为CLR确保每个AppDomain只能执行一次静态构造函数。这对于您的情况就足够了,因为您使用的是静态映射器(AutoMapper.Mapper),它也是每个AppDomain一个。