2009-11-12 41 views
8

AutoMapper'ı denetleyicilere enjekte etmek için çalışıyorum. Code Camp Server'ın uygulanmasını seviyorum. AutoMapper'ın IMappingEngine'i etrafında bir paket oluşturur. Bağımlılık enjeksiyon StructureMap kullanılarak yapılır. Ama benim projem için Castle Windsor'u kullanmam gerek. Peki, Windsor kullanarak aşağıdaki bağımlılık enjeksiyonunu ve kurulumunu nasıl uygularız? Castle Windsor'da hat-line eşdeğer bir uygulama aramıyorum. Bunu yapmak isterseniz, lütfen çekinmeyin. Bunun yerine, StructureMap'in Kayıt ve Profiline Windsor eş değeri nedir? Aşağıdaki gibi CreateMap <> tanımlamak için Profile ihtiyacım var.Enjeksiyon AutoMapper

Teşekkürler.

Toplantı kontrolörü:

public MeetingController(IMeetingMapper meetingMapper, ...) 

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

    ...... 
} 

Oto Mapper Sicil:

public class AutoMapperRegistry : Registry 
{ 

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

Toplantı Mapper Profili:

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

cevap

3

Eğer Windsor kaydetmek nasıl yani?

FactorySupportFacility yumruk atmanız gerekebilir ... Şu anda kontrol etme şansım yok.

container.AddFacility<FactorySupportFacility>(); 

ve sonra

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

StructureMap'deki Profil bölümünden ne haber? Mapper.CreateMap .ForMember() MeetingMapperProfile sınıfından çağrılır. Castle Windsor'da bunu nasıl yapabilirim? Teşekkürler. – Roger

+0

Bu profil nedir? Bu ne işe yarıyor? Yapılandırma yöntemini kastediyorsanız, bunu yaptığınızdan, bileşenlerinizi kapsayıcıya kaydettirdiğinizde, Yapısal Arayüz'teki AFAICS –

+0

Profili, bir hizmetin farklı somut uygulamalarını devre dışı bırakabilme kabiliyetine sahip değildir. Kullanım süreleri bağlamında bağlı olarak. Ancak, Toplantı profiline bakarsanız, aslında bunu yapmaz. Toplantı Profilindeki Mapper.CreateMap <>. ForMember (...), MeetingMapper'ın _mappingEngine.Map() işlevini çağırmasından önce çağrılmalıdır.Toplantı Profilinin şu anda yaptığı şeyi yapmak için Windsor'da bir Tesis oluşturmayı düşünüyorum. Ne düşünüyorsun? Teşekkürler. – Roger

2

Ben Castle Windsor aşina değilim ama burada StructureMap sözdizimi. Kayıt defterinizi biraz farklı kurmanız gerekir. IMappingEngine öğesini Mapper.Engine olarak ayarlamak yerine, birkaç arabirim daha yapılandırmanız gerekir. Biraz daha fazla iş var ama bu profili kayıtın bir parçası olarak ayarlamanıza izin verecek.

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

Bu biraz eski farkındayım ama kale Windsor kullanmak ve AutoMapper profilleri bir yükleyici kullanılarak yüklenen almak oldukça kolay oldu:

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

Bu yükleyici gösterilen MeetingMapperProfile alacağını Soru veya AutoMapper'ın Profile'u temel alan başka herhangi bir sınıf.