请参阅以下代码:
public class Test : ITest
{
public ITest2 _iTest2;
public int _id;
public string _name;
public Test(ITest2 test2)
{
_iTest2 = test2;
}
}
public interface ITest
{
}
public class Test2 : ITest2
{
}
public interface ITest2
{
}
public class Test3 : ITest3
{
public int _id;
public string _name;
}
public interface ITest3
{
}
我在Global.asax中有以下内容:
Mapper.Initialize(m =>
{
m.CreateMap<DataLayer.Test3, BusinessLayer.Test>().ConstructUsing(opt => new BusinessLayer.Test(new BusinessLayer.Test2()));
});
我可以在我的客户端应用中映射这些类型:
cfg.CreateMap<DataLayer.Test3, BusinessLayer.Test>().ConstructUsing(opt => new BusinessLayer.Test(new BusinessLayer.Test2()));
如何使用Castle Windsor映射类型,而不必为Test和Test2使用new关键字?
我读了另一个答案,有人建议这样做:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Types.FromAssembly(Assembly.GetExecutingAssembly()).BasedOn(typeof(IValueResolver<,,>)));
// container.Register(Types.FromAssembly(Assembly.GetExecutingAssembly()).BasedOn<IValueResolver>());
container.Register(Types.FromThisAssembly().BasedOn<Profile>().WithServiceBase());
var profiles = container.ResolveAll<Profile>();
// Add your list of profiles to the mapper configuration here
Mapper.Initialize(m => {
m.ConstructServicesUsing(container.Resolve);
profiles.ToList().ForEach(p => m.AddProfile(p));
});
// I'm not sure about this as I haven't used AutoMapper for a while,
// but I assume you want to resolve the static mapper instance
container.Register(Component.For<IMapper>().Instance(Mapper.Instance));
}
我必须这样做:
cfg.CreateMap<DataLayer.Test3, BusinessLayer.Test>().ConstructUsing(opt => new BusinessLayer.Test(new BusinessLayer.Test2()));
或者AutoMapper是否能够使用以下方式映射类型:
cfg.CreateMap<DataLayer.Test3, BusinessLayer.Test>()
答案 0 :(得分:1)
为了让AutoMapper使用Windsor创建目标类型,您需要配置两件事:
告诉AutoMapper(按映射)实际使用上述配置
var container = new WindsorContainer();
Mapper.Initialize(m =>
{
m.ConstructServicesUsing(container.Resolve);
m.CreateMap<Test3, ITest>().ConstructUsingServiceLocator(); // This is important!
});
container.Register(Component.For<ITest>().ImplementedBy<Test>());
container.Register(Component.For<ITest2>().ImplementedBy<Test2>());
container.Register(Component.For<ITest3>().ImplementedBy<Test3>());
var test3 = new Test3();
var test1 = Mapper.Instance.Map<Test3, ITest>(test3);
答案 1 :(得分:0)
对于需要使用xamarin 3.6,prism 7.1和automapper 8.1的用户来说,这是对我有用的。
在App.xml.cs文件中
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
/// other registrations ...
containerRegistry.RegisterSingleton<IMapperProvider, MapperProvider>();
containerRegistry.RegisterInstance(typeof(IMapper), GetMapper(containerRegistry));
}
/// <summary>
/// This function required in order for injection into custom automapper resolvers
/// </summary>
private IMapper GetMapper(IContainerRegistry container)
{
var mp = container.GetContainer().Resolve<IMapperProvider>(new[] { container });
return mp.GetMapper();
}
映射器提供程序如下:
public class MapperProvider : IMapperProvider
{
private readonly IContainerRegistry _container;
public MapperProvider(IContainerRegistry container)
{
_container = container;
}
public IMapper GetMapper()
{
var config = new MapperConfiguration(cfg =>
{
cfg.ConstructServicesUsing(t => _container.GetContainer().Resolve(t));
// any custom profile statement such as
cfg.AddProfile<MappingSourcesProfile>();
// ....
});
return config.CreateMapper();
}
}
现在我的自定义解析器可以工作了,例如:
public class BarcodesResolver : IValueResolver<repo.Book, Book, List<Barcode>>
{
private readonly IMapper _mapper;
public BarcodesResolver(IMapper mapper)
{
_mapper = mapper;
}
public List<Barcode> Resolve(repo.Book source, Book destination, List<Barcode> destMember, ResolutionContext context)
{
repo.BookAttributes groupedAttribs = JsonConvert.DeserializeObject<repo.BookAttributes>(source.BookAttributes);
return _mapper.Map<List<repo.Barcode>, List<Barcode>>(groupedAttribs.Barcodes);
}
}
这里要解决的难题是如何指定将containerRegistry传递给MapperProvider的构造函数。也许有更好的方法可以做到这一点,但至少可以奏效。
到达cfg.ConstructServicesUsing(t => _container.GetContainer().Resolve(t));
行也很晦涩,因为那里似乎没有什么例子。