2009-11-12 8 views
8

私はAutoMapperをコントローラに注入しようとしています。私はCode Camp Serverの実装が気に入っています。 AutoMapperのIMappingEngineの周りにラッパーを作成します。依存性注入はStructureMapを使用して行われます。しかし私は私のプロジェクトにCastle Windsorを使用する必要があります。では、ウィンザーを使用して、次のような依存性注入と設定をどのように実装しますか?私はCastle Windsorでline-by-lineに相当する実装を探しているわけではありません。あなたがそれをしたい場合は、自由に感じてください。代わりに、ウィンザーはStructureMapのレジストリとプロファイルに相当するものは何ですか?次のように、CreateMap <を定義するプロファイルが必要です。AutoMapperを注入する

ありがとうございました。

会議コントローラ

public MeetingController(IMeetingMapper meetingMapper, ...) 

会議マッパー

public class MeetingMapper : IMeetingMapper 
{ 

    private readonly IMappingEngine _mappingEngine; 

    public MeetingMapper(IMappingEngine mappingEngine) 
    { 
     _mappingEngine = mappingEngine; 
    } 

    public MeetingInput Map(Meeting model) 
    { 
     return _mappingEngine.Map<Meeting, MeetingInput>(model);  
    } 

    ...... 
} 

自動マッパーレジストリ

public class AutoMapperRegistry : Registry 
{ 

    public AutoMapperRegistry() 
    { 
     ForRequestedType<IMappingEngine>().TheDefault.Is.ConstructedBy(() => Mapper.Engine); 
    } 
} 

会議マッパープロフィール:

public class MeetingMapperProfile : Profile 
{ 

    public static Func<Type, object> CreateDependencyCallback = (type) => Activator.CreateInstance(type); 

    public T CreateDependency<T>() 
    { 
     return (T)CreateDependencyCallback(typeof(T)); 
    } 

    protected override void Configure() 
    { 
     Mapper.CreateMap<MeetingInput, Meeting>().ConstructUsing(
      input => CreateDependency<IMeetingRepository>().GetById(input.Id) ?? new Meeting()) 

     .ForMember(x => x.UserGroup, o => o.MapFrom(x => x.UserGroupId)) 
     .ForMember(x => x.Address, o => o.Ignore()) 
     .ForMember(x => x.City, o => o.Ignore()) 
     .ForMember(x => x.Region, o => o.Ignore()) 
     .ForMember(x => x.PostalCode, o => o.Ignore()) 
     .ForMember(x => x.ChangeAuditInfo, o => o.Ignore()); 
    } 
} 

答えて

3

あなたはウィンザーに登録しない方法を意味ですか?

FactorySupportFacility fistを登録する必要があるかもしれません...私はこの時点でチェックする方法がありません。

container.AddFacility<FactorySupportFacility>(); 

、その後

container.Register(Component.For<IMappingEngine>().UsingFactoryMethod(()=> 
      Mapper.Engine)); 
+0

StructureMapのプロファイルパートはどうですか? Mapper.CreateMap .ForMember()はMeetingMapperProfileクラスから呼び出されます。どのように城ウィンザーでそれを行うには?ありがとう。 – Roger

+0

このプロフィールは何ですか?それは何をするためのものか?構成メソッドを意味するだけではなく、コンテナにコンポーネントを登録する場合は、コンテナに依存しません。AFAICS –

+0

StructureMapのプロファイルは、サービスの異なる具体的な実装(つまり、クラス)を実行時に使用するコンテキストに応じて実行します。しかし、ミーティングのプロファイルを見ると、それは実際には行われていません。 Mapper.CreateMap <>。MeetingMapperが_mappingEngine.Map()を呼び出す前に、ミーティングプロファイルのForMember(...)を呼び出す必要があります。私はウィンザーでミーティング・プロフィールが今やっていることをする施設を作ることを考えています。どう思いますか?ありがとう。 – Roger

2

私は城ウィンザーに慣れていないんだが、ここでのStructureMapの構文は次のとおりです。あなたのレジストリを少し異なる設定する必要があります。 IMappingEngineをMapper.Engineに設定する代わりに、いくつかのインターフェイスを設定する必要があります。これはもう少し作業ですが、これにより登録の一部としてプロファイルを設定することができます。

public AutoMapperRegistry() 
{ 
    //type mapping 
    For<ConfigurationStore>() 
     .Singleton() 
     .Use(ctx => 
     { 
      ITypeMapFactory factory = ctx.GetInstance<ITypeMapFactory>(); 
      ConfigurationStore store 
       = new ConfigurationStore(factory, MapperRegistry.AllMappers()); 
      IConfiguration cfg = store; 
      //Here's where you load your profile 
      cfg.AddProfile<MeetingMapperProfile>(); 
      store.AssertConfigurationIsValid(); 
      return store; 
     }); 
    For<IConfigurationProvider>().Use(ctx => ctx.GetInstance<ConfigurationStore>()); 
    For<IConfiguration>().Use(ctx => ctx.GetInstance<ConfigurationStore>()); 
    For<IMappingEngine>().Use<MappingEngine>(); 
    For<ITypeMapFactory>().Use<TypeMapFactory>(); 
} 
2

私は、これは少し古いですが実現するが、私は城ウィンザーを使用し、AutoMapperプロファイルは、インストーラを使用してロードされるために非常に容易となっています:

using System.Linq; 
using System.Reflection; 

using AutoMapper; 

using Castle.MicroKernel.Registration; 
using Castle.MicroKernel.SubSystems.Configuration; 
using Castle.Windsor; 

namespace YourNamespace 
{ 
    public class AutoMapperInstaller : IWindsorInstaller 
    { 
     public void Install(IWindsorContainer container, IConfigurationStore store) 
     { 
      Mapper.Initialize(m => m.ConstructServicesUsing(container.Resolve)); 

      container.Register(Types.FromAssembly(Assembly.GetExecutingAssembly()).BasedOn<IValueResolver>()); 
      container.Register(Types.FromThisAssembly().BasedOn<Profile>().WithServiceBase()); 
      var profiles = container.ResolveAll<Profile>(); 
      profiles.ToList().ForEach(p => Mapper.AddProfile(p)); 

      container.Register(Component.For<IMappingEngine>().Instance(Mapper.Engine)); 
     } 
    } 
} 

このインストーラが示さMeetingMapperProfileを拾うでしょう質問、またはAutoMapperのProfileに基づく他のどのクラスでも使用できます。

関連する問題