次の回答で説明されているように、次の方法を使用して、マッパーのインスタンスを作成します。
var platformSpecificRegistry = AutoMapper.Internal.PlatformAdapter.Resolve<IPlatformSpecificMapperRegistry>();
platformSpecificRegistry.Initialize();
var autoMapperCfg = new AutoMapper.ConfigurationStore(new TypeMapFactory(), AutoMapper.Mappers.MapperRegistry.Mappers);
var mappingEngine = new AutoMapper.MappingEngine(_autoMapperCfg);
次の質問で説明されているように:
AutoMapperコンテキストに応じてオブジェクトAをオブジェクトBに異なる方法でマップする方法 。
次のような Automapper profile クラスを使用して[再利用]してマッパーのインスタンスを作成するにはどうすればよいですか?
public class ApiTestClassToTestClassMappingProfile : Profile
{
protected override void Configure()
{
base.Configure();
Mapper.CreateMap<ApiTestClass, TestClass>()
.IgnoreAllNonExisting();
}
}
このような機能が必要な理由を説明するために、次のメソッドを使用して、すべてのAutomapperプロファイルクラスをIoCコンテナ[CastleWindsor]に登録します。
IoC.WindsorContainer.Register(Types.FromThisAssembly()
.BasedOn<Profile>()
.WithServiceBase()
.Configure(c => c.LifeStyle.Is(LifestyleType.Singleton)));
var profiles = IoC.WindsorContainer.ResolveAll<Profile>();
foreach (var profile in profiles)
{
Mapper.AddProfile(profile);
}
IoC.WindsorContainer.Register(Component.For<IMappingEngine>().Instance(Mapper.Engine));
上記は静的マッパークラスを初期化する必要性を完全に満たしていますが、[非静的マッパーを使用して]インスタンスマッパーを作成するためにオートマッパープロファイルクラスを再利用する方法がまったくわかりません。
プロファイルが正しいCreateMap呼び出しを呼び出すことを確認する必要があります。
public class ApiTestClassToTestClassMappingProfile : Profile
{
protected override void Configure()
{
CreateMap<ApiTestClass, TestClass>()
.IgnoreAllNonExisting();
}
}
基本プロファイルクラスのCreateMapは、そのマップをそのプロファイルおよび構成に関連付けます。
また、IgnoreAllNonExistingは、CreateMap呼び出しのMemberList.Sourceオプションに置き換えられる必要があります。つまり、「宛先タイプの代わりに、検証するメンバーのリストとしてソースタイプを使用する」ということです。
これは、プロファイルを使用してMapperConfigurationを作成する方法です
public static class MappingProfile
{
public static MapperConfiguration InitializeAutoMapper()
{
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new WebMappingProfile()); //mapping between Web and Business layer objects
cfg.AddProfile(new BLProfile()); // mapping between Business and DB layer objects
});
return config;
}
}
プロファイルの例
//Profile number one saved in Web layer
public class WebMappingProfile : Profile
{
public WebMappingProfile()
{
CreateMap<Question, QuestionModel>();
CreateMap<QuestionModel, Question>();
/*etc...*/
}
}
//Profile number two save in Business layer
public class BLProfile: Profile
{
public BLProfile()
{
CreateMap<BLModels.SubModels.Address, DataAccess.Models.EF.Address>();
/*etc....*/
}
}
オートマッパーをDIフレームワークに配線します(これはUnityです)
public static class UnityWebActivator
{
/// <summary>Integrates Unity when the application starts.</summary>
public static void Start()
{
var container = UnityConfig.GetConfiguredContainer();
var mapper = MappingProfile.InitializeAutoMapper().CreateMapper();
container.RegisterInstance<IMapper>(mapper);
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
// TODO: Uncomment if you want to use PerRequestLifetimeManager
// Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
/// <summary>Disposes the Unity container when the application is shut down.</summary>
public static void Shutdown()
{
var container = UnityConfig.GetConfiguredContainer();
container.Dispose();
}
}
マッピングにクラスでIMapperを使用する
public class BaseService
{
protected IMapper _mapper;
public BaseService(IMapper mapper)
{
_mapper = mapper;
}
public void AutoMapperDemo(){
var questions = GetQuestions(token);
return _mapper.Map<IEnumerable<Question>, IEnumerable<QuestionModel>>(questions);
}
public IEnumerable<Question> GetQuestions(token){
/*logic to get Questions*/
}
}
私の元の投稿はここにあります: http://www.codeproject.com/Articles/1129953/ASP-MVC-with-Automapper-Profiles
最終的に、マッパーインスタンスファクトリを次のように作成しました。
using AutoMapper;
using AutoMapper.Mappers;
using System.Collections.Generic;
public class MapperFactory<TSource,TDestination> where TSource : new() where TDestination : new()
{
private readonly ConfigurationStore _config;
public MapperFactory(IEnumerable<Profile> profiles)
{
var platformSpecificRegistry = AutoMapper.Internal.PlatformAdapter.Resolve<IPlatformSpecificMapperRegistry>();
platformSpecificRegistry.Initialize();
_config = new AutoMapper.ConfigurationStore(new TypeMapFactory(), AutoMapper.Mappers.MapperRegistry.Mappers);
foreach (var profile in profiles)
{
_config.AddProfile(profile);
}
}
public TDestination Map(TSource sourceItem)
{
using (var mappingEngine = new MappingEngine(_config))
{
return mappingEngine.Map<TSource, TDestination>(sourceItem);
}
}
}
そして今、私は私のソリューションで次のようなコードを持つことができます:
var profiles = new Profile[]
{
new ApiTestClassToTestClassMappingProfile1(),
new ApiTestClassToTestClassMappingProfile2(),
new ApiTestClassToTestClassMappingProfile3()
};
var mapper = new MapperFactory<ApiTestClass, TestClass>(profiles);
var mappedItem = mapper.Map(testClassInstance);
上記のコードは、プロファイルクラスの再利用性を最大限に高めます。