Кажется, вы хотите сохранить свои сущности в доменном слое "чистыми", создав частный установщик. Это хорошая вещь. Один из способов обработки тестов или сопоставления DTO с сущностями заключается в создании метода расширения, который дает доступ к частному установщику.
Этот метод использует библиотеку FastMember Марка Гравелла:
using FastMember;
...
public static class DomainExtensions
{
private static readonly IDictionary<Type, TypeAccessor> _accessors = new Dictionary<Type, TypeAccessor>();
public static T With<T, TFieldOrProperty>(this T instance, Expression<Func<T, TFieldOrProperty>> fieldOrProperty, TFieldOrProperty value)
where T : class
{
if (instance == null)
return null;
if (!(fieldOrProperty.Body is MemberExpression member))
throw new ArgumentException($"Expression '{fieldOrProperty}' is not for a property or field.");
try
{
if (!_accessors.TryGetValue(typeof(T), out var ta))
lock (_accessors)
ta = _accessors[typeof(T)] = TypeAccessor.Create(typeof(T), true);
if (ta[instance, member.Member.Name] != null)
{
ta[instance, member.Member.Name] = value;
return instance;
}
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
// fallback to reflection
var fi = member.Member as FieldInfo;
fi?.SetValue(instance, value);
var pi = member.Member as PropertyInfo;
pi?.SetValue(instance, value);
return instance;
}
Тогда вы используете это так:
workingGroup.With(wg => wg.WorkingGroupId, 2);
Таким образом, ваша сущность остается чистой. Теперь вы можете сказать: «Хорошо, теперь я могу обойти сущность, доступную только для чтения». Это правда, но разработчик должен был бы явно и сознательно нарушить этот доступ, вызвав With()
.
Если тестовые случаи - единственное место, где вам нужен этот доступ, поместите метод With()
в сборку вместе с вашими тестами. Это гарантирует, что ваш производственный код не может установить идентификатор.