3

我正在组合一个 .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>();

根据 AutoMapper 的设计指南,每个 AppDomain 只应执行一次(因为这是一项昂贵的操作)。由于该库可以在任意数量的可能环境中使用(ASP.NET、WinForms 应用程序、WPF 应用程序、单元测试运行程序等),在这种情况下如何正确设置地图?

显然,我的代码可以为客户端公开某种方法来调用“初始化事物”(在本例中为映射器)并假设他们确实在应用程序启动过程中的正确时间进行了该调用,但这看起来像强加给图书馆消费者的一个非常蹩脚的要求。

任何人对我有任何建议和/或可以将我指向 GitHub、Codeplex 等已经在做类似事情的开源项目?

4

2 回答 2

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;
}

这样你就不需要依赖你的消费者来进行初始化。

于 2012-06-29T11:01:18.997 回答
2

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

于 2012-07-14T18:54:21.787 回答