Я пытаюсь придерживаться принципов DDD для коллекций C # , см. Больше здесь
И я замечаю, что метод построения модели для начального начального числа HasData опирается на метод Add ICollection .Есть ли способ обойти или обмануть этот метод, когда он вызывается из процесса обновления / переноса базы данных?
Все, что я до сих пор делал, чтобы обмануть его, следует по этому пути.
1) Создание оболочкивокруг ICollection с именем ReadOnlyKollection
2) Иметь закрытую ICollection на модели, чтобы не подвергать внешний мир коллекции.
3) Выставлять обертку, делающую устаревшейAdd и некоторые другие методы, которые будут вызывать NotImplementedException, если они используются.
Тем не менее, метод Add, несмотря на устаревшее предупреждение, можно использовать, поскольку он все еще общедоступен и необходим для начального метода HasData, используемого в процессе обновления / переноса базы данных.
Я думаю, по крайней мере, ограничить вызывающие методы изнутри метода Add класса оболочки.
Мне было бы полезно узнать вызывающий член, когда HasData будет запускаться и разрешать только этот методобработать и выдать исключение для любого другого.
Обратите внимание, что CallerMethodNФункцию типа компиляции ame нельзя использовать, поскольку она нарушит контракт интерфейса ICollectoion.
Есть какие-либо идеи, чтобы избежать предоставления свойств частной коллекции Entity Framework в соответствии с принципами DDD?(и все еще есть расширение метода HasData для обновления / переноса процесса базы данных).см. код ниже ..
public interface IReadOnlyKollection<T> : ICollection<T>
{
}
public class ReadOnlyKollection<T> : IReadOnlyKollection<T>
{
private readonly ICollection<T> _collection;
public ReadOnlyKollection(ICollection<T> collection)
{
_collection = collection;
}
public int Count => _collection.Count;
public bool IsReadOnly => _collection.IsReadOnly;
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<T> GetEnumerator() => _collection.GetEnumerator();
public bool Contains(T item) => _collection.Contains(item);
public void CopyTo(T[] array, int arrayIndex) => _collection.CopyTo(array, arrayIndex);
[Obsolete]
public void Add(T item) => _collection.Add(item); // CallerMethodName trick to be applied here or ??
[Obsolete]
public void Clear() => throw new NotImplementedException();
[Obsolete]
public bool Remove(T item) => throw new NotImplementedException();
}
public class StateProvince
{
public StateProvince() //EF Constructor
{
}
public StateProvince(string id, string name)
: this(name)
{
Id = id;
}
public string Id { get; protected set; }
public string Name { get; protected set; }
public string CountryRegionId { get; protected set; }
public virtual CountryRegion CountryRegion { get; protected set; }
}
public class CountryRegion
{
public CountryRegion() //EF Constructor
{
}
public CountryRegion(string id, string name)
: this(name)
{
Id = id;
}
public string Id { get; protected set; }
public string Name { get; protected set; }
private readonly ICollection<StateProvince> _stateProvinces = new List<StateProvince>(); // Private collection for DDD usage
public IReadOnlyKollection<StateProvince> StateProvinces => new ReadOnlyKollection<StateProvince>(_stateProvinces); // Public like read only collection public immutable exposure
}
EntityTypeBuilder<StateProvince> // Code reduced for brevity
builder.HasIndex(e => e.CountryRegionId);
builder.Property(e => e.Id).IsUnicode(false).HasMaxLength(3).ValueGeneratedNever();
builder.Property(e => e.CountryRegionId).IsRequired().IsUnicode(false).HasMaxLength(3);
builder.Property(e => e.Name).IsRequired().HasMaxLength(50);
EntityTypeBuilder<CountryRegion> builder // Code reduced for brevity
builder.Property(e => e.Id).IsUnicode(false).HasMaxLength(3).ValueGeneratedNever();
builder.Property(e => e.Name).IsRequired().HasMaxLength(50);
builder.HasMany(e => e.StateProvinces)
.WithOne(e => e.CountryRegion)
.HasForeignKey(e => e.CountryRegionId)
.IsRequired()
.OnDelete(DeleteBehavior.Restrict);
builder.HasData(GetData())
private static object[] GetData()
{
return new object[]
{
new { Id = "AF", Name = "Afghanistan", IsDeleted = false, LastModified = DateTimeOffset.UtcNow },
new { Id = "AL", Name = "Albania", IsDeleted = false, LastModified = DateTimeOffset.UtcNow },
new { Id = "DZ", Name = "Algeria", IsDeleted = false, LastModified = DateTimeOffset.UtcNow },
new { Id = "AS", Name = "American Samoa", IsDeleted = false, LastModified = DateTimeOffset.UtcNow },