2009-11-12 5 views
8

Ho lavorato all'iniezione di AutoMapper nei controller. Mi piace l'implementazione di Code Camp Server. Crea un wrapper attorno a IMappingEngine di AutoMapper. L'iniezione della dipendenza viene eseguita utilizzando StructureMap. Ma ho bisogno di usare Castle Windsor per il mio progetto. Quindi, come possiamo implementare la seguente iniezione di dipendenze e set-up usando Windsor? Non sto cercando l'implementazione equivalente linea per linea nel castello di Windsor. Se vuoi farlo, sentiti libero. Invece, qual è l'equivalente di Windsor del registro e del profilo di StructureMap? Ho bisogno che Profile definisca CreateMap <> come il seguente.Inject AutoMapper

Grazie.

regolatore Meeting:

public MeetingController(IMeetingMapper meetingMapper, ...) 

Meeting 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 Registro:

public class AutoMapperRegistry : Registry 
{ 

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

Meeting Mapper Profilo:

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

risposta

3

vuoi dire come si fa a registrarlo a Windsor?

potrebbe essere necessario registrare FactorySupportFacility pugno ... Non ho modo di verificare in questo momento.

container.AddFacility<FactorySupportFacility>(); 

e poi

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

E la parte del profilo in StructureMap? Mapper.CreateMap .ForMember() viene chiamato dalla classe MeetingMapperProfile. Come si fa a Castle Windsor? Grazie. – Roger

+0

cos'è questo Profilo? Che cosa fa? Se si intende solo il metodo Configure, di quello in cui si registrano i componenti nel contenitore, non ha alcuna dipendenza dal contenitore. Il profilo AFAICS –

+0

in StructureMap è la capacità di disattivare diverse implementazioni concrete di un servizio (ad esempio classe) in fase di esecuzione a seconda del contesto in cui vengono utilizzati. Ma se guardi il profilo Meeting, in realtà non lo fa. Mapper.CreateMap <>. ForMember (...) nel Profilo riunione deve essere chiamato prima che MeetingMapper richiami _mappingEngine.Map().Sto pensando di creare una struttura a Windsor per fare ciò che il Profilo Meeting sta facendo in questo momento. Cosa ne pensi? Grazie. – Roger

2

Non ho dimestichezza con il Castello di Windsor, ma qui è la sintassi StructureMap. Dovresti configurare un registro un po 'diverso. Invece di impostare IMappingEngine su Mapper.Engine, dovrai configurare alcune altre interfacce. È un po 'più di lavoro ma questo ti permetterà di impostare il profilo come parte della registrazione.

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

Mi rendo conto che è un po 'vecchio, ma io uso il Castello di Windsor, ed è stato abbastanza facile da ottenere profili automapper caricati utilizzando un programma di installazione:

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

Questo programma di installazione sarebbe prendere il MeetingMapperProfile mostrato nella domanda o in qualsiasi altra classe basata su AutoMapper's Profile.