2009-11-12 10 views
8

J'ai travaillé sur l'injection d'AutoMapper dans les contrôleurs. J'aime l'implémentation de Code Camp Server. Il crée un wrapper autour de IMappingEngine d'AutoMapper. L'injection de dépendance est effectuée à l'aide de StructureMap. Mais je dois utiliser Castle Windsor pour mon projet. Alors, comment pouvons-nous mettre en œuvre l'injection de dépendance suivante et mettre en place en utilisant Windsor? Je ne suis pas à la recherche d'une mise en œuvre équivalente ligne par ligne à Castle Windsor. Si vous voulez faire cela, n'hésitez pas. Au lieu de cela, quel est l'équivalent Windsor du Registre et du Profil de StructureMap? J'ai besoin de profil pour définir CreateMap <> comme le suivant.Injecter AutoMapper

Merci.

contrôleur de réunion:

public MeetingController(IMeetingMapper meetingMapper, ...) 

Réunion 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 Registre:

public class AutoMapperRegistry : Registry 
{ 

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

Réunion Mapper Profil:

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

Répondre

3

vous dire comment inscrivez-vous dans Windsor?

vous devez enregistrer FactorySupportFacility fist ... Je n'ai aucun moyen de vérifier en ce moment.

container.AddFacility<FactorySupportFacility>(); 

puis

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

Qu'en est-il de la partie Profil dans StructureMap? Mapper.CreateMap .ForMember() est appelée à partir de la classe MeetingMapperProfile. Comment faire ça à Castle Windsor? Merci. – Roger

+0

Quel est ce profil? Qu'est ce que ça fait? Si vous voulez dire simplement la méthode Configure, que vous le faites, où vous enregistrez vos composants dans le conteneur, elle n'a aucune dépendance sur le conteneur. AFAICS –

+0

ProfileModel est la possibilité de changer différentes implémentations concrètes d'un service (ie classe) à l'exécution en fonction du contexte dans lequel ils sont utilisés. Mais si vous regardez le profil de réunion, il ne le fait pas réellement. Le Mapper.CreateMap <>. ForMember (...) dans le profil de réunion doit être appelé avant que le MeetingMapper appelle _mappingEngine.Map().Je pense à la création d'une installation à Windsor pour faire ce que fait le profil de la réunion en ce moment. Qu'est-ce que tu penses? Merci. – Roger

2

Je ne suis pas familier avec le château de Windsor, mais voici la syntaxe StructureMap. Vous auriez besoin de mettre en place votre registre un peu différent. Au lieu de définir IMappingEngine sur Mapper.Engine, vous devrez configurer quelques autres interfaces. C'est un peu plus de travail mais cela vous permettra de définir le profil dans le cadre de l'inscription.

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

Je sais que cela est un peu vieux, mais j'utilise le château de Windsor, et il a été assez facile d'obtenir des profils AutoMapper chargés à l'aide d'un installateur:

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

Ce programme d'installation ramassait le MeetingMapperProfile montré dans la question, ou toute autre classe basée sur Profile AutoMapper.