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());