Проблема с Automapper и Windsor - PullRequest
5 голосов
/ 21 июня 2011

У меня проблема с Automapper, когда я пытаюсь использовать собственный распознаватель, который использует внедрение зависимостей.

У меня есть следующая модель:

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

и модель следующего вида:

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

    public int CountryId { get; set; }

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

для отображения я использую следующий код:

Mapper.Map(registrationViewModel, user);

ранее я регистрировал следующее:

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

Мой BasicProfile выглядит следующим образом:

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

    }
}

Пользовательский преобразователь выполняется следующим образом:

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

}

Когда выполняется код сопоставления, я получаю следующее исключение:

AutoMapper.AutoMapperMappingException: попытка сопоставить ViewModels.RegistrationViewModel с Models.User. Использование конфигурации сопоставления для ViewModels.RegistrationViewModel для Models.User Исключение типа 'AutoMapper.AutoMapperMappingException' было сгенерировано. ----> AutoMapper.AutoMapperMappingException: при попытке сопоставить ViewModels.RegistrationViewModel с LModels.Country. Использование конфигурации сопоставления для ViewModels.RegistrationViewModel для Models.User Недвижимость назначения: Страна Исключение типа 'AutoMapper.AutoMapperMappingException' было сгенерировано. ----> System.ArgumentException: Тип 'Mapping.LoadingEntityResolver`1 [Models.Country]' не имеет конструктора по умолчанию

Понятия не имею, что может быть не так. Возможно, это что-то с созданием резольвера. Когда я пробую следующее, нет проблем:

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

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

Я был бы рад любой помощи.

С уважением
Лукаш

1 Ответ

4 голосов
/ 21 июня 2011

У вас есть довольно полезные вещи из DI :-) Я бы не хотел, чтобы AutoMapper разрешал сущности из базы данных или чего-то еще. Делает код трудным для понимания, и последующая жизнь объектов может стать кошмаром.

В любом случае, чтобы решить вашу проблему, просто поменяйте местами заказ (не так):

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

до (правильно):

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