在过去的几天里,我一直在使用不同的解决方案来将DTO映射到VS2013,EF6,WCF服务应用项目的实体。
这是一个相当大的项目,目前正在进行重大的重构,以便对遗留代码进行测试(以及将ORM从OpenAccess移植到EF6)。
说实话,我以前从未使用过AutoMapper,但我看到的确非常喜欢,所以我开始在演示应用程序中测试它,说实话我有点惭愧,因为我无法实现有效的解决方案经过数小时的修补和谷歌搜索。以下是该项目的细分:
基于WCF服务应用程序模板的项目(.svc文件w /代码隐藏)。 将Unity 3.x用于我的IoC容器,从而创建自己的ServiceHostFactory继承自UnityServiceHostFactory。 使用当前的AutoMapper nuget包。 DTO和DAL按预期位于两个独立的库中,这两个库都由服务应用程序项目引用。 我的目标很简单(我认为):在我的合成根中连接并创建我的所有地图,并将必要的对象(使用我的DI容器)注入到具有DTO领域知识的类中,并引用我的DAL库。因此,任何需要转换的人都只需要引用转换库。
问题:嗯,有几个......
1)我无法在Unity中找到AutoMapper的工作示例。在Web上多次引用以在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 lib中对AutoMapper的明显必要的引用之外,我将注入瞬时,配置对象(假设IConfiguration或IConfigurationProvider)以及我将哪个类注入到WCF服务的构造函数中获得对必要对象的访问权限。
我知道#3有点模糊,但由于我无法在我的Unity容器中绑定AutoMapper,我无法测试/试用/错误以找出其他问题。
任何指针都会非常感激。
更新
所以我现在有一个正常测试的工作解决方案,但仍然希望确认我遵循任何既定的最佳实践。
首先,AutoMapper的Unity容器注册(截至2013年11月13日)v3.x如下所示:
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()方法。我创建了一个测试映射,它既可以执行类似命名属性的自动映射,也可以执行自定义映射。我在演示应用程序中这样做主要有两个原因:
所有这些都是喋喋不休,这就是我能够实现的目标。
我将非常感谢任何指导性的建议,但我现在有一个工作演示,我可以在完成这个大型重构时对其进行测试。
最终更新
我通过添加另一个库(MappingLib)稍微更改了演示项目,并以静态方法将所有DTO转换和映射移动到了它。虽然我在Unity容器初始化之后仍然在我的组合根中调用静态方法,但这给了我更多的灵活性,能够在我的NUnit单元测试库中调用相同的地图创建方法,有效地消除了围绕自动映射器的任何重复代码并使其非常可测试。