首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在标记为内部的属性上使用AutoMapper?

如何在标记为内部的属性上使用AutoMapper?
EN

Stack Overflow用户
提问于 2010-07-09 05:14:45
回答 3查看 2.4K关注 0票数 6

我有几个项目的解决方案。业务组件项目、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

代码语言:javascript
复制
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)
        );
}
EN

回答 3

Stack Overflow用户

发布于 2016-05-24 02:16:40

只需在initialize方法中设置configuration对象的ShouldMapProperty属性。

这是一个使用静态API的示例,但是,您应该能够通过使用非静态API以类似的方式实现相同的效果。

代码语言:javascript
复制
Mapper.Initialize(i =>
{
    i.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
    i.CreateMap<Source, Target>();                
});

如果您使用配置文件,这必须放在构造函数中:

代码语言:javascript
复制
public class MyProfile : Profile
{
    public MyProfile()
    {
        ShouldMapProperty = arg => arg.GetMethod.IsPublic || arg.GetMethod.IsAssembly;

        // The mappings here.
    }
}
票数 12
EN

Stack Overflow用户

发布于 2010-07-09 09:45:45

您是否考虑过映射到接口?让数据契约实现一个接口,然后映射到该接口。然后,您可以显式实现该接口,从而有效地隐藏这些成员。

票数 0
EN

Stack Overflow用户

发布于 2011-11-03 12:26:29

使用这个。它在私有字段和内部字段上都工作得很好。

http://ragingpenguin.com/code/privatefieldresolver.cs.txt

用法:

代码语言:javascript
复制
// 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")));

就像一种护身符。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3208057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档