Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 依赖于另一个配置文件的自动映射配置文件_C#_Automapper - Fatal编程技术网

C# 依赖于另一个配置文件的自动映射配置文件

C# 依赖于另一个配置文件的自动映射配置文件,c#,automapper,C#,Automapper,我对这些问题也有同样的看法: 以下是一个例子: namespace Request { public class Source { [System.Xml.Serialization.XmlElementAttribute("Class1", typeof(Class1))] [System.Xml.Serialization.XmlElementAttribute("Class2", typeof(Class2))] [Sys

我对这些问题也有同样的看法:

  • 以下是一个例子:

    namespace Request
    {
        public class Source
        {
            [System.Xml.Serialization.XmlElementAttribute("Class1", typeof(Class1))]
            [System.Xml.Serialization.XmlElementAttribute("Class2", typeof(Class2))]
            [System.Xml.Serialization.XmlElementAttribute("Class3", typeof(Class3))]
            public object Item { get; set; }
        }
    
        public class Class1 { ... }
        public class Class2 { ... }
        public class Class3 { ... }
    }
    
    namespace Response
    {
        public class Destination
        {
            [System.Xml.Serialization.XmlElementAttribute("Class1", typeof(Class1))]
            [System.Xml.Serialization.XmlElementAttribute("Class2", typeof(Class2))]
            [System.Xml.Serialization.XmlElementAttribute("Class3", typeof(Class3))]
            public object Item { get; set; }
        }
    
        public class Class1 { ... }
        public class Class2 { ... }
        public class Class3 { ... }
    }
    
    <>代码> AutoPuffer-<代码>不考虑映射这样的属性的<代码> XMLeltEngftEng/<代码>。我可以通过使用反射来解决它:

    public object Map(object source, Type destinationParentType, string destinationPropertyName)
    {
        var prop = destinationParentType.GetProperties(BindingFlags.Public | BindingFlags.Instance).SingleOrDefault(p =>
            string.Compare(p.Name, destinationPropertyName, StringComparison.Ordinal) == 0);
    
        if (prop == null || prop.CustomAttributes == null) return null;
    
        var attribute = Attribute.GetCustomAttributes(prop, typeof(XmlElementAttribute))
            .Cast<XmlElementAttribute>().SingleOrDefault(a =>
                string.Compare(a.Type.Name, source.GetType().Name, StringComparison.Ordinal) == 0);
    
        return attribute == null ? null : AutoMapper.Mapper.Map(source, source.GetType(), attribute.Type);
    }
    
    然后使用
    xmlementattributes
    的属性映射器:

    public class AttributeProfile : AutoMapper.Profile
    {
        public AttributeProfile()
        {
            CreateMap<Source.Class1, Destination.Class1>();
            CreateMap<Source.Class2, Destination.Class2>();
            CreateMap<Source.Class3, Destination.Class3>();
        }
    }
    
    但是我在
    MainProfile
    类的
    AttributeMapper
    属性中得到了一个未设置为对象实例的
    对象引用

    Dependency
    是否是
    AutoMapper
    配置文件的一个问题?这就是为什么我无法实现这一点?是否有其他方法可以使用
    AutoMapper
    修复此
    xmlementattributes
    映射

    我愿意寻找其他可以帮助我的方法。

    感谢您分享他的想法。如果可以的话,我会把你的评论作为回答

    我创建了一个
    XmlElementAttributeResolver
    (更通用的名称更合适),如下所示:

    public class XmlElementAttributeResolver : IMemberValueResolver<object, object, object, object>
    {
        public object Resolve(object source, object destination, object sourceMember, object destMember, ResolutionContext context)
        {
            var sourceMemberType = sourceMember.GetType();
            var destinationNamespace = destination.GetType().Namespace;
            var destinationMemberType = destination.GetType().Assembly.GetTypes()
                .FirstOrDefault(t => t.Name == sourceMemberType.Name && t.Namespace == destinationNamespace);
    
            return destinationMemberType == null
                ? null
                : context.Mapper.Map(sourceMember, sourceMemberType, destinationMemberType);
        }
    }
    
    由于解析程序在
    ResolutionContext
    参数中有
    RuntimeMapper
    ,因此我不需要将映射程序注入解析程序。因此,我的mapper容器更简单:

    var config = new MapperConfiguration(c =>
    {
        c.AddProfile<MainProfile>();
        //Other Profiles
    });
    
    Container.RegisterInstance(config.CreateMapper(), new ContainerControlledLifetimeManager());
    
    var config=新的MapperConfiguration(c=>
    {
    c、 AddProfile();
    //其他概况
    });
    Container.RegisterInstance(config.CreateMapper(),新ContainerControlledLifetimeManager());
    
    配置文件是单例的,您需要将其注入到解析器中。请参阅。当您想将DI与构造函数逻辑相结合时,最合理的方法是构造函数注入,而不是属性注入,对吗?@LucianBargaoanu,谢谢,不知怎的,我已经做到了。@grek40如果您属于
    概要文件
    类,我无法通过构造函数注入依赖项。但我不太确定。
    
    var mainConfig = new MapperConfiguration(c =>
    {
        c.AddProfile<MainProfile>();
        //Other Profiles
    });
    
    var helperConfig = new MapperConfiguration(c => 
    { 
        c.AddProfile<AttributeProfile>(); 
    });
    
    Container.RegisterType<AttributeMapper>();
    Container.RegisterInstance(mainConfig.CreateMapper(), new ContainerControlledLifetimeManager());
    Container.RegisterInstance("AttributeMapper", helperConfig.CreateMapper(),
        new ContainerControlledLifetimeManager());
    
    public class AttributeMapper
    {
        private readonly IMapper _mapper;
    
        public AttributeMapper([Dependency("AttributeMapper")] IMapper mapper)
        {
            _mapper = mapper;
        }
    
        public object Map(object source, Type destinationParentType, string destinationPropertyName)
        {
            //Same method from the one above, but I am using _mapper instead of AutoMapper.Mapper.Map    
            return attribute == null ? null : _mapper.Map(source, source.GetType(), attribute.Type);
        }
    }
    
    public class XmlElementAttributeResolver : IMemberValueResolver<object, object, object, object>
    {
        public object Resolve(object source, object destination, object sourceMember, object destMember, ResolutionContext context)
        {
            var sourceMemberType = sourceMember.GetType();
            var destinationNamespace = destination.GetType().Namespace;
            var destinationMemberType = destination.GetType().Assembly.GetTypes()
                .FirstOrDefault(t => t.Name == sourceMemberType.Name && t.Namespace == destinationNamespace);
    
            return destinationMemberType == null
                ? null
                : context.Mapper.Map(sourceMember, sourceMemberType, destinationMemberType);
        }
    }
    
    public class MainProfile : AutoMapper.Profile
    {
        //[Dependency]
        //internal AttributeMapper AttributeMapper { get; set; } <--This is not resolved from UnityContainer
    
        public MainProfile()
        {
            CreateMap ...
            CreateMap<SourceType, DestinationType>()
                .ForMember(d => d.Item, o => o.ResolveUsing<XmlElementAttributeResolver, object>(s => s.Item));
        }
    }
    
    var config = new MapperConfiguration(c =>
    {
        c.AddProfile<MainProfile>();
        //Other Profiles
    });
    
    Container.RegisterInstance(config.CreateMapper(), new ContainerControlledLifetimeManager());