I think it's fairly simple question but I am still unable to find any better solution for it. So after researching on this subject, I thought to ask this question here to have an expert opinion.
Basically, I am working on WPF application and I have defined GenericObserableCollection<T>
implementing ObservableCollection<T>
and most of the collections implement it to have a standard approach all over the project.
[Serializable]
[CollectionDataContract]
public class GenericObservableCollection<T> : ObservableCollection<T>
{
public GenericObservableCollection() { }
public GenericObservableCollection(IEnumerable<T> collection)
: base(collection) { }
}
[Serializable]
[CollectionDataContract]
public class GenericRuleCollection : GenericObservableCollection<IRule>
{
public GenericRuleCollection() { }
public GenericRuleCollection(IEnumerable<IRule> collection)
: base(collection) { }
}
Initially, it was all good but later when Entity Framework came into the picture I had to change the domain design drastically because EF requires exposing ICollection<T>
for mapping. At that point, I was confused keeping minimum changes and adapt to EF because I was new in it.
Later after researching, I came across few good articles handling this scenario.
- Exposing Private Collection Properties to Entity Framework
- Mapping but not exposing ICollections in Entity Framework
I applied the same approach in my application domain creating ChildrenStorage
to hold ICollection<GenericRule>
as a requirement for EF.
Now I am looking for a smart and elegant approach to keep both of my collections, i.e. ChildrenStorage
and Children
collection in sync when items are added and/or removed. Since Children
collection is the one that will get modified via UI so I want to keep track of any changes made to Children
and wants to sync ChildrenStorage
.
[Serializable]
[DataContract]
public abstract class GenericContainerRule : GenericRule
{
protected GenericContainerRule() : this(null)
{
ChildrenStorage = new List<GenericRule>();
}
protected GenericContainerRule(string name) : base(name)
{
ChildrenStorage = new List<GenericRule>();
}
public void AddChild(IRule rule)
{
ChildrenStorage.Add(rule as GenericRule);
_children = new GenericRuleCollection(ChildrenStorage);
OnPropertyChanged(nameof(Children));
}
public class OrMappings
{
public static Expression<Func<GenericContainerRule, ICollection<GenericRule>>> ChildrenAccessor = t => t.ChildrenStorage;
}
[DataMember]
protected ICollection<GenericRule> ChildrenStorage { get; set; }
private GenericRuleCollection _children;
public GenericRuleCollection Children => _children ?? (_children = new GenericRuleCollection(ChildrenStorage));
private GenericRuleCollection _children;
[DataMember]
public virtual GenericRuleCollection Children
{
get { return _children; }
private set { SetProperty(ref _children, value); }
}
}