2

在过去的几天里,我一直在使用不同的解决方案来将 DTO 映射到 VS2013、EF6、WCF 服务应用程序项目的实体。

这是一个相当大的项目,目前正在进行重大重构以测试遗留代码(以及将 ORM 从 OpenAccess 移植到 EF6)。

老实说,我以前从未使用过 AutoMapper,但我看到的东西我真的很喜欢,所以我开始在一个演示应用程序中对其进行测试,老实说,我有点羞愧,因为我在几个小时后无法实现一个可行的解决方案修补和谷歌搜索。以下是该项目的细分:

基于 WCF 服务应用程序模板的项目(带有代码的 .svc 文件)。将 Unity 3.x 用于我的 IoC 容器,从而创建我自己的继承自 UnityServiceHostFactory 的 ServiceHostFactory。使用当前的 AutoMapper nuget 包。DTO 和 DAL 按预期位于两个单独的库中,服务应用程序项目都引用了这两个库。我的目标很简单(我认为):在我的组合根目录中连接并创建我的所有地图,并将必要的对象(使用我的 DI 容器)注入到具有 DTO 领域知识和对我的 DAL 库的引用的类中。因此,任何需要转换的人都只需要引用转换库。

问题:嗯,有几个......

1) 我在 Unity 的任何地方都找不到 AutoMapper 的工作示例。在网络上多次引用的用于在 Unity 中注册 AutoMapper 的代码片段(见下文)引用了一个似乎不再存在的配置类,我找不到任何关于其弃用的文档:

container.RegisterType<AutoMapper.Configuration, AutoMapper.Configuration>(new PerThreadLifetimeManager(), new InjectionConstructor(typeof(ITypeMapFactory), AutoMapper.Mappers.MapperRegistry.AllMappers())).RegisterType<ITypeMapFactory,
TypeMapFactoy>().RegisterType<IConfiguration, AutoMapper.Configuration>().RegisterType<IConfigurationProvider, AutoMapper.Configuration>().RegisterType<IMappingEngine, MappingEngine>();

2)在哪里自己创建地图......我假设我可以在我的 ServiceHostFactory 中执行此操作,但那是正确的地方吗?那里有一个 Bootstrapper 项目,但我还没有走那条路(还),如果可能的话,我想避免它。

3) 除了在 DTO 库中对 AutoMapper 的明显必要的引用之外,我将向实例中注入什么、配置对象(假设为 IConfiguration 或 IConfigurationProvider)以及我将哪个类注入到 WCF 服务的构造函数中以获得访问权限必要的对象。

我知道#3 有点含糊,但由于我无法将 AutoMapper 绑定到我的 Unity 容器中,因此我无法通过测试/试验/错误来找出其他问题。

任何指针将不胜感激。

更新

所以我现在有一个可以正确测试的有效解决方案,但仍然希望确认我正在遵循任何已建立的最佳实践。

首先,AutoMapper(截至 2013 年 11 月 13 日)v3.x 的 Unity 容器注册如下所示:

container .RegisterType<ConfigurationStore, ConfigurationStore> ( new ContainerControlledLifetimeManager() , new InjectionConstructor(typeof(ITypeMapFactory) , MapperRegistry.AllMappers()) ) .RegisterType<IConfigurationProvider, ConfigurationStore>() .RegisterType<IConfiguration, ConfigurationStore>() .RegisterType<IMappingEngine, MappingEngine>() .RegisterType<ITypeMapFactory, TypeMapFactory>();

在完成所有容器注册之后,我在 ConfigureContainer() 中创建并调用了 RegisterMaps() 方法。我创建了一个测试映射,它既可以为类似命名的属性进行自动映射,也可以进行自定义映射。我在我的演示应用程序中这样做主要有两个原因:

  1. 我还不知道托管在 IIS 中并注入 Unity 的 WCF 应用程序中的 AutoMapper 足以完全理解其行为。我似乎不必将任何类型的配置对象注入到我的库中来进行转换,我仍在阅读源代码以了解其实现。
  2. 据我了解,这里有一个缓存机制,如果在缓存中找不到映射,它将即时创建它。虽然这在理论上很好,但我可以测试在我的组合根中发生的映射的唯一方法是执行某种自定义映射,然后在执行映射并返回 DTO 的库中调用 Mapper.Map。

抛开所有这些喋喋不休,这就是我能够完成的事情。

  • WCF 服务应用程序(组合根)注入所有必要的对象,包括我的 DtoConversionMapper 实例。
  • 该项目由 WCF 服务应用程序(comp root)、DtoLib、DalLib、ContractsLib(接口)组成。
  • 在我的 ServiceFactoryHost 中,我能够创建映射,包括自定义映射(即映射不同于我的 DTO 和 EF 6 实体之间的命名属性)。
  • DtoConversionMapper 类位于 DtoLib 库中,如下所示: IExampleDto GetExampleDto(ExampleEntity entity);
  • 任何引用 DtoLib 的库都可以来回转换,包括将发生绝大多数这些调用的服务应用程序。

任何指导性建议都将不胜感激,但我现在确实有一个工作演示,我可以在完成这个大型重构的同时进行测试。

最终更新

我通过添加另一个库 (MappingLib) 稍微更改了演示项目,并以静态方法将我的所有 DTO 转换和映射移动到它。虽然在 Unity 容器初始化后我仍然在我的组合根中调用静态方法,但这为我提供了额外的灵活性,能够在我的 NUnit 单元测试库中调用相同的地图创建方法,有效地消除了围绕自动映射器的任何重复代码并使其非常可测试。

4

0 回答 0