我有几个项目的解决方案。业务组件项目、MVC应用程序、DTO和ViewModels项目、业务组件单元测试项目和MVC单元测试项目。总而言之,并不是太不寻常。业务组件具有对多个WCF端点的服务引用。在业务组件中,使用AutoMapper将来自WCF端点的数据契约自动映射到ViewModels所需的数据中。我想解决的问题是,自动生成的WCF代理中的数据契约POCO都是公共的,所以当我从MVC应用程序中引用我的业务组件时(实际上是通过StructureMap注入的,所以如果需要的话,我可以使用模拟业务组件),我可以从web应用程序中访问WCF POCO。由于其他几个开发人员将在web应用程序上工作,我不希望他们被诱惑直接使用WCF POCO,而是通过业务组件。因此,我删除了业务组件中的服务引用,并添加了一个使用/INTERNAL标志调用SVCUTIL.exe的脚本,以便自动生成的类被标记为内部类而不是公共类。但是,现在AutoMapper不能映射到我的数据契约POCO,也不能映射到POCO的。
我找不到任何说明如何让AutoMapper使用内部属性的文档,所以我从github中提取了源代码,并修改了TypeInfo.cs,使其忽略了字段并包含了非公共成员。现在,我的解决方案工作得很好,但有了自己的自定义版本的AutoMapper,感觉就有点老土了。似乎应该有一种方法来映射从WCF数据合同POCO的,而不必是公开的。我遗漏了什么?
更改的TypeInfo.cs
private IEnumerable<MemberInfo> GetAllPublicReadableMembers()
{
IEnumerable<Type> typesToScan = new[] { Type, Type.BaseType };
if (Type.IsInterface)
typesToScan = typesToScan.Concat(Type.GetInterfaces());
return typesToScan
.Where(x => x != null)
.SelectMany(x => x.FindMembers(
MemberTypes.Property, //changed this
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, //and this
(m, f) => m is FieldInfo ||
m is PropertyInfo && ((PropertyInfo)m).CanRead && !((PropertyInfo)m).GetIndexParameters().Any(),
null)
);
}发布于 2016-05-24 02:16:40
只需在initialize方法中设置configuration对象的ShouldMapProperty属性。
这是一个使用静态API的示例,但是,您应该能够通过使用非静态API以类似的方式实现相同的效果。
Mapper.Initialize(i =>
{
i.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
i.CreateMap<Source, Target>();
});如果您使用配置文件,这必须放在构造函数中:
public class MyProfile : Profile
{
public MyProfile()
{
ShouldMapProperty = arg => arg.GetMethod.IsPublic || arg.GetMethod.IsAssembly;
// The mappings here.
}
}发布于 2010-07-09 09:45:45
您是否考虑过映射到接口?让数据契约实现一个接口,然后映射到该接口。然后,您可以显式实现该接口,从而有效地隐藏这些成员。
发布于 2011-11-03 12:26:29
使用这个。它在私有字段和内部字段上都工作得很好。
http://ragingpenguin.com/code/privatefieldresolver.cs.txt
用法:
// in one library
public class Foo
{
internal string _bar = "some value";
}
// in another library
public class FooModel
{
public string Bar { get; set; }
}
Mapper.CreateMap<Foo, FooModel>()
.ForMember(x => x.Bar, o => o.ResolveUsing(new PrivateFieldResolver("_bar")));就像一种护身符。
https://stackoverflow.com/questions/3208057
复制相似问题