Skip to content

Instantly share code, notes, and snippets.

@JobaDiniz
Created May 19, 2020 20:44
Show Gist options
  • Save JobaDiniz/628ceda9133843fad447152f1b9e8cc9 to your computer and use it in GitHub Desktop.
Save JobaDiniz/628ceda9133843fad447152f1b9e8cc9 to your computer and use it in GitHub Desktop.
Plug-and-play bug example of AutoMapper Explicit Expand feature
using AutoMapper.QueryableExtensions;
using System;
using System.Linq;
using Xunit;
namespace AutoMapper.UnitTests.Bug
{
public class ExplicitExpansionWithIncludeBase
{
/*********** Source Types ***********/
abstract class EntityBase
{
public EntityBase() => Id = Guid.NewGuid();
public Guid Id { get; set; }
public User CreatedBy { get; set; }
public User ModifiedBy { get; set; }
}
class User { }
class Computer : EntityBase { }
class Script : EntityBase
{
public Computer Computer { get; set; }
}
/*********** Destination Types ***********/
class EntityBaseModel
{
public Guid Id { get; set; }
public UserModel CreatedBy { get; set; }
public UserModel ModifiedBy { get; set; }
}
class UserModel { }
class ComputerModel : EntityBaseModel { }
class ScriptModel : EntityBaseModel
{
public ComputerModel Computer { get; set; }
}
private IConfigurationProvider BuildConfiguration()
{
return new MapperConfiguration(cfg =>
{
cfg.CreateMap<User, UserModel>();
cfg.CreateMap<EntityBase, EntityBaseModel>()
.MaxDepth(1)
.ForMember(d => d.ModifiedBy, o => o.ExplicitExpansion())
.ForMember(d => d.CreatedBy, o => o.ExplicitExpansion());
cfg.CreateMap<Computer, ComputerModel>()
.MaxDepth(1)
.ForMember(d => d.ModifiedBy, o => o.ExplicitExpansion())
.ForMember(d => d.CreatedBy, o => o.ExplicitExpansion());
cfg.CreateMap<Script, ScriptModel>()
.MaxDepth(1)
.ForMember(d => d.Computer, o => o.ExplicitExpansion())
.ForMember(d => d.ModifiedBy, o => o.ExplicitExpansion())
.ForMember(d => d.CreatedBy, o => o.ExplicitExpansion());
});
}
private Script CreateModel()
{
var computer = new Computer()
{
CreatedBy = new User(),
ModifiedBy = new User(),
};
return new Script()
{
CreatedBy = new User(),
ModifiedBy = new User(),
Computer = computer
};
}
[Fact]
public void ComputerCreatedBy_should_be_null_because_it_was_not_specified_in_members_to_expand_when_using_expressions()
{
// arrange
var config = BuildConfiguration();
var script = CreateModel();
// act
var scriptModel = new[] { script }.AsQueryable()
.ProjectTo<ScriptModel>(config, c => c.Computer, c => c.CreatedBy).Single(); // Expand Computer and CreatedBy from Script
// assert
Assert.Null(scriptModel.Computer.CreatedBy); //Not Explicit call to 'expand'
}
[Fact]
public void ComputerCreatedBy_should_be_null_because_it_was_not_specified_in_members_to_expand()
{
// arrange
var config = BuildConfiguration();
var script = CreateModel();
// act
var scriptModel = new[] { script }.AsQueryable()
.ProjectTo<ScriptModel>(config, null, "Computer", "CreatedBy").Single(); // Expand Computer and CreatedBy from Script
// assert
Assert.Null(scriptModel.Computer.CreatedBy); //CreatedBy from Computer was not specified in 'membersToExpand'
}
[Fact]
public void ComputerCreatedBy_shouldnt_be_null_BUT_ScriptCreatedBy_should_be_null_because_it_was_not_specified_in_members_to_expand()
{
// arrange
var config = BuildConfiguration();
var script = CreateModel();
// act
var scriptModel = new[] { script }.AsQueryable()
.ProjectTo<ScriptModel>(config, null, "Computer.CreatedBy").Single(); // Expand Computer.CreatedBy from Script
// assert
Assert.NotNull(scriptModel.Computer.CreatedBy);
Assert.Null(scriptModel.CreatedBy); //CreatedBy from Script was not specified in 'membersToExpand'
}
[Fact]
public void ScriptCreatedBy_should_be_null_because_it_was_not_specified_in_members_to_expand()
{
// arrange
var config = BuildConfiguration();
var script = CreateModel();
// act
var scriptModel = new[] { script }.AsQueryable()
.ProjectTo<ScriptModel>(config, null, "Computer.CreatedBy").Single(); // Expand Computer.CreatedBy from Script
// assert
Assert.Null(scriptModel.CreatedBy); //CreatedBy from Script was not specified in 'membersToExpand'
}
}
public class ExplicitExpansionWithIncludeBaseUsingNewKeyword
{
/*********** Source Types ***********/
abstract class EntityBase
{
public EntityBase() => Id = Guid.NewGuid();
public Guid Id { get; set; }
public User CreatedBy { get; set; }
public User ModifiedBy { get; set; }
}
class User { }
class Computer : EntityBase { }
class Script : EntityBase
{
public Computer Computer { get; set; }
}
/*********** Destination Types ***********/
class EntityBaseModel
{
public Guid Id { get; set; }
public UserModel CreatedBy { get; set; }
public UserModel ModifiedBy { get; set; }
}
class UserModel { }
class ComputerModel : EntityBaseModel
{
public new UserModel CreatedBy { get; set; } //NOTE: the 'new' keyword here make the tests pass
}
class ScriptModel : EntityBaseModel
{
public new UserModel CreatedBy { get; set; } //NOTE: the 'new' keyword here make the tests pass
public ComputerModel Computer { get; set; }
}
private IConfigurationProvider BuildConfiguration()
{
return new MapperConfiguration(cfg =>
{
cfg.CreateMap<User, UserModel>();
cfg.CreateMap<EntityBase, EntityBaseModel>()
.MaxDepth(1)
.ForMember(d => d.ModifiedBy, o => o.ExplicitExpansion())
.ForMember(d => d.CreatedBy, o => o.ExplicitExpansion());
cfg.CreateMap<Computer, ComputerModel>()
.MaxDepth(1)
.ForMember(d => d.ModifiedBy, o => o.ExplicitExpansion())
.ForMember(d => d.CreatedBy, o => o.ExplicitExpansion());
cfg.CreateMap<Script, ScriptModel>()
.MaxDepth(1)
.ForMember(d => d.Computer, o => o.ExplicitExpansion())
.ForMember(d => d.ModifiedBy, o => o.ExplicitExpansion())
.ForMember(d => d.CreatedBy, o => o.ExplicitExpansion());
});
}
private Script CreateModel()
{
var computer = new Computer()
{
CreatedBy = new User(),
ModifiedBy = new User(),
};
return new Script()
{
CreatedBy = new User(),
ModifiedBy = new User(),
Computer = computer
};
}
[Fact]
public void ComputerCreatedBy_should_be_null_because_it_was_not_specified_in_members_to_expand_when_using_expressions()
{
// arrange
var config = BuildConfiguration();
var script = CreateModel();
// act
var scriptModel = new[] { script }.AsQueryable()
.ProjectTo<ScriptModel>(config, c => c.Computer, c => c.CreatedBy).Single(); // Expand Computer and CreatedBy from Script
// assert
Assert.Null(scriptModel.Computer.CreatedBy); //Not Explicit call to 'expand'
}
[Fact]
public void ComputerCreatedBy_should_be_null_because_it_was_not_specified_in_members_to_expand()
{
// arrange
var config = BuildConfiguration();
var script = CreateModel();
// act
var scriptModel = new[] { script }.AsQueryable()
.ProjectTo<ScriptModel>(config, null, "Computer", "CreatedBy").Single(); // Expand Computer and CreatedBy from Script
// assert
Assert.Null(scriptModel.Computer.CreatedBy); //CreatedBy from Computer was not specified in 'membersToExpand'
}
[Fact]
public void ComputerCreatedBy_shouldnt_be_null_BUT_ScriptCreatedBy_should_be_null_because_it_was_not_specified_in_members_to_expand()
{
// arrange
var config = BuildConfiguration();
var script = CreateModel();
// act
var scriptModel = new[] { script }.AsQueryable()
.ProjectTo<ScriptModel>(config, null, "Computer.CreatedBy").Single(); // Expand Computer.CreatedBy from Script
// assert
Assert.NotNull(scriptModel.Computer.CreatedBy);
Assert.Null(scriptModel.CreatedBy); //CreatedBy from Script was not specified in 'membersToExpand'
}
[Fact]
public void ScriptCreatedBy_should_be_null_because_it_was_not_specified_in_members_to_expand()
{
// arrange
var config = BuildConfiguration();
var script = CreateModel();
// act
var scriptModel = new[] { script }.AsQueryable()
.ProjectTo<ScriptModel>(config, null, "Computer.CreatedBy").Single(); // Expand Computer.CreatedBy from Script
// assert
Assert.Null(scriptModel.CreatedBy); //CreatedBy from Script was not specified in 'membersToExpand'
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment