Что NHibernate делает с моим Iesi.Collections.ISet?

Я пытаюсь протестировать мой сервис, который называется GetUsersForRole. Он принимает простую строку и передает ее в мой RoleRepository для работы с NHibernate и получения коллекции ролей с переданной строкой для его RoleName. Для этого у меня есть функция Find в моем RoleRepository, которая вызывает этот код:

ICriteria crit = rb.unitOfWork.Session.CreateCriteria(typeof(Entity));
crit.SetCacheable(false);
foreach (object[] criteriaItem in criteria)
{
   crit.Add(Expression.Eq((string)criteriaItem[0], criteriaItem[1]));
}

return crit.List().Cast<Entity>();

Таким образом, приведенный выше код вернет список ролей, и в нем есть свойство, определенное как Iesi.Collections.ISet, которое называется Users. Если к данной роли привязаны пользователи (через многие-ко-многим), это свойство заполняется.

Отсюда я имею дело с результатом этой функции Find и получаю первую роль, а затем использую ValueInjector, чтобы сопоставить свойство role.Users с набором IEnumerable. Это работает на 100%. Вот код, который делает это:

var role = _roleRepo.Find(new List<object[]>()
                               {
                                   new object[] {"Name", roleName}
                               }).FirstOrDefault();

if (role == null)
    return null;

MapperFactory.ClearMappers();
MapperFactory.AddMapper(new ISetToIEnumerable<User, UserDTO>());

var users = Mapper.Map<Iesi.Collections.ISet, IEnumerable<UserDTO>>(role.Users);

return users;

Я использую класс Automapper Simulation для значения Injector, чтобы иметь дело с заданными отображениями. Это можно найти здесь. Мне пришлось сделать специальный Mapper для работы с Iesi.Collections.ISet для IEnumerable отображений:

public class ISetToIEnumerable<TSource, TTarget> : TypeMapper<Iesi.Collections.ISet, IEnumerable<TTarget>>
{
    public override IEnumerable<TTarget> Map(Iesi.Collections.ISet source, IEnumerable<TTarget> target)
    {
        base.Map(source, target);

        List<TTarget> entities = new List<TTarget>();
        foreach (var entity in source)
        {
            entities.Add(Mapper.Map<TSource, TTarget>((TSource)entity));
        }
        target = entities.AsEnumerable();
        return target;
    }
}

Опять же, это работает на 100%. В классе сопоставления ISetToIEnumerable источник аргумента выглядит как Iesi.Collections.ISet {NHibernate.Collection.PersistantSet}. Вот где что-то не так, когда я пытаюсь это проверить.

Я пытаюсь проверить успешность запуска с помощью этого модульного теста:

    [Test]
    public void GetUsersForRole_success()
    {
        // Arrange
        var roles = new List<Role>();
        var role = new Role()
                       {
                           Name = "role1",
                           Users = {new User() {Username = "user1"}, new User() {Username = "user2"}}
                       };
        roles.Add(role);

        _mockRoleRepository.Setup(m => m.Find(It.IsAny<IList<object[]>>())).Returns(roles);

        var service = GetDefaultService();

        // Act
        var users = service.GetUsersForRole("role1");

        Assert.That(users.Count() == 2);
    }

Когда я отлаживаю это и вхожу в вызов service.GetUsersForRole("role1"), я возвращаю мои смоделированные данные из моего mockRoleRepository. Проблема здесь в том, что мое свойство role.Users возвращает типы как Iesi.Collections.HashedSet (именно так создается его экземпляр в конструкторе сущностей как для тестирования, так и для реальных запусков с NHibernate). Теперь это становится главной проблемой в моем классе ISetToIEnumerable. Мой источник наткнулся на Iesi.Collections.HashedSet.

Я знаю, что не смогу напечатать свой макет с помощью NHibernate.Collection.PersistantSet из-за отсутствия экземпляра сеанса NHibernate. Есть ли у кого-нибудь мысли о том, что здесь происходит и как я смогу воспроизвести то, что NHibernate делает, с моим Iesi.Collections.ISet в моем расположении моих фиктивных данных?

1 ответ

Решение

Если я правильно понимаю, у вас есть ISet<T> в вашей доменной модели? Почему бы вам не использовать это в качестве источника в вашем картографе? Почему не универсальный интерфейс?

Другой альтернативой является то, что у вас есть общий интерфейс как для универсального, так и не универсального интерфейса, например, IEnumerable в качестве источника в вашем устройстве отображения.

Другие вопросы по тегам