2009-11-12 1 views
8

Я работал над инжектированием AutoMapper в контроллеры. Мне нравится реализация Code Camp Server. Он создает обертку вокруг IMAPpingEngine AutoMapper. Инъекция зависимостей выполняется с помощью StructureMap. Но мне нужно использовать Castle Windsor для моего проекта. Итак, как мы реализуем следующую инъекцию и настройку зависимостей с помощью Windsor? Я не ищу линейную эквивалентную реализацию в Castle Windsor. Если вы хотите сделать это, пожалуйста, не стесняйтесь. Вместо этого, что такое Виндзорский эквивалент реестра и профиля StructureMap? Мне нужен профиль, чтобы определить CreateMap <> как показано ниже.Inject AutoMapper

Спасибо.

контроллер Встреча:

public MeetingController(IMeetingMapper meetingMapper, ...) 

Встреча Mapper:

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

    ...... 
} 

Auto Mapper Registry:

public class AutoMapperRegistry : Registry 
{ 

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

Встреча Mapper профиля:

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 ... У меня нет возможности проверить этот момент.

container.AddFacility<FactorySupportFacility>(); 

, а затем

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

Как насчет части профиля в StructureMap? Mapper.CreateMap . ForMember() вызывается из класса MeetingMapperProfile. Как это сделать в замке Виндзор? Благодарю. – Roger

+0

Что это за профайл? Что оно делает? Если вы имеете в виду только метод Configure, чем вы это делаете, когда вы регистрируете свои компоненты в контейнере, он не имеет никакого отношения к контейнеру. AFAICS –

+0

Профиль в StructureMap - это возможность отключать различные конкретные реализации службы (т.е. класс) во время выполнения в зависимости от контекста, в котором они используются. Но если вы посмотрите на профиль Совещания, на самом деле это не делается. Mapper.CreateMap <>. ForMember (...) в профиле собрания должен вызываться до вызова MeetingMapper _mappingEngine.Map().Я думаю о создании объекта в Виндзоре, чтобы делать то, что делает профиль собрания прямо сейчас. Как вы думаете? Благодарю. – 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's Profile.