2011-06-21 19 views
5

Mam problem z Automapper, gdy próbuję użyć niestandardowego przelicznika, który wykorzystuje wtrysk zależności.Problem z Automapper i Windsor

Mam następujący model:

public class User : Entity 
{ 
    public virtual string Name { get; set; } 
    public virtual Country Country { get; set; } 
} 

public class Country : Entity 
{ 
    public virtual string Name { get; set; } 
} 

i następujący widok model:

public class RegistrationViewModel 
{ 
    [Required]   
    public string Name { get; set; } 

    public int CountryId { get; set; } 

    public IEnumerable<Country> Countries { get; set; } 
} 

w celu map używam następujący kod:

Mapper.Map(registrationViewModel, user); 

wcześniej zarejestrować następujące:

Mapper.Reset(); 
container = new WindsorContainer(); 
container.AddFacility<FactorySupportFacility>(); 
container.Register(Component.For<ISession>(). 
           UsingFactoryMethod(() => NHibernateSessionFactory.RetrieveSession()). 
           LifeStyle.Is(LifestyleType.Transient)); 
container.Register(Component.For(typeof(LoadingEntityResolver<>)).ImplementedBy(typeof(LoadingEntityResolver<>)).LifeStyle.Transient); 
Mapper.Initialize(x => 
     { 
      x.AddProfile<BasicProfile>(); 
      x.ConstructServicesUsing(container.Resolve); 
     }); 

My BasicProfile jest następujący:

public class BasicProfile : Profile 
{ 
    public const string VIEW_MODEL = "MyBasicProfile"; 

    public override string ProfileName 
    { 
     get { return VIEW_MODEL; } 
    } 

    protected override void Configure() 
    { 
     CreateMaps(); 
    } 

    private void CreateMaps() 
    { 
     CreateMap<RegistrationViewModel, User>() 
      .ForMember(dest => dest.Country, _ => _.ResolveUsing<LoadingEntityResolver<Country>>().FromMember(src => src.CountryId)) 
      ); 

    } 
} 

Zwyczaj rezolwer odbywa się w następujący sposób:

public class LoadingEntityResolver<TEntity> : ValueResolver<int, TEntity> 
    where TEntity: Entity 
{ 
    private readonly ISession _session; 

    public LoadingEntityResolver(ISession session) 
    { 
     _session = session; 
    } 

    protected override TEntity ResolveCore(int source) 
    { 
     return _session.Load<TEntity>(source); 
    } 

} 

Gdy kod mapowania polega na uruchomieniu pojawia się następujący wyjątek:

AutoMapper.AutoMapperMappingException: Próba mapowania ViewModels.RegistrationViewModel na Models.User. Przy użyciu konfiguracji odwzorowania dla ViewModels.RegistrationViewModel do Models.User Wyjątek typu "AutoMapper.AutoMapperMappingException" został zgłoszony. ----> AutoMapper.AutoMapperMappingException: Próba mapowania ViewModels.RegistrationViewModel na LModels.Country. Przy użyciu konfiguracji odwzorowania dla ViewModels.RegistrationViewModel do Models.User Właściwość docelowa: kraj Wyjątek typu "AutoMapper.AutoMapperMappingException" został zgłoszony. ----> System.ArgumentException: Typ 'Mapping.LoadingEntityResolver`1 [Models.Country]' nie ma domyślnego konstruktora

nie mam pojęcia co może być nie tak. Prawdopodobnie jest to coś z budowaniem resolwera. Kiedy próbuję następuje nie ma problemu:

var resolver = container.Resolve<LoadingEntityResolver<Country>>(); 

Assert.IsInstanceOf<LoadingEntityResolver<Country>>(resolver); 

byłbym greatfull za wszelką pomoc.

poważaniem
Łukasz

Odpowiedz

4

masz jakieś dość mocny DI rzeczy dzieje się tutaj :-) Chciałbym uniknąć podmioty AutoMapper rozwiązywaniu z bazy danych lub cokolwiek. Sprawia, że ​​kod jest trudny do zrozumienia, a podążanie za przedmiotami przez całe życie może stać się koszmarem.

W każdym razie, aby naprawić problem, po prostu zamienić kolejności od (źle):

Mapper.Initialize(x => 
{ 
    x.AddProfile<BasicProfile>(); 
    x.ConstructServicesUsing(container.Resolve); 
}); 

do (poprawne):

Mapper.Initialize(x => 
{ 
    x.ConstructServicesUsing(container.Resolve); 
    x.AddProfile<BasicProfile>(); 
}); 
+0

bardzo dziękuję za pomoc. Ta prosta zmiana rozwiązała mój problem. Jeśli uważasz, że podejście, którego używam, nie jest dobre - co polecasz wtedy? – GUZ