How to track if (List<T>)collection is modified? - c#

I have a my custom collection derived from List(.MyItem.)
I want to trace if my collection is modified, how can I do that?
I am able to track Add Remove operations etc...by implement new definition of them but I don't see any method in List that gives me opportunity to track if collection is modified...

Take a look at a new type called ObservableCollection<T>. It has built in notification of changes, and it should be fairly simple to change your base class to this from list as both are very similar.

Related

Ddd where enforce aggregate invariant?

Given an aggregate order I would like to know how I can force invariance.
Public class Order(){}
AddOrderItem(){}
AddPaymentMethod(){}
}
Var order = new Order();
_orderRepository.Save(order); //This was bad.
The invariance is given by the fact that Order must have at least one OrderItem within the collection and PaymentMethod.
But that means that sometimes it doesn't have to be called AddOrderItem/AddPaymentMethod so everything would break.
I would not like to pass all the OrderItem through the constructor since the order has not been generated yet. I would also not like to have an order validation service as this can lead to bad development and someone can forget to call the validator.
Is it possible to create a factory? if so how do you add items making the order methods private (since no one can add items without it being through the factory)?
Or would it be a better option to create a validatorOrderCreatedDomainEventHandler after firing the domain event (OrderCreated) thus validating all the consistency before calling Save to the repository?
What is the best option to enforce this invariant?
There is a distinction between (A) keeping an entity in a valid state with every change (including when being created) and (B) preventing an entity from being persisted/processed.
(A) means for example having a property telling us whether or not an order is ready to be processed:
bool ReadyToBeProcessed => OrderItems.Count > 0 && PaymentMethod is not null
Now an empty order with no payment method is not considered to be broken and may be persisted.
(B) means performing a validation before processing an order. Whether or not you implement domain events is less important: calling validations can be forgotten in either way. The point is you always have a single flow (endpoint) to process an order, and it is your responsibility to perform necessary validations e.g. throwing an exception if ReadyToBeProcessed is false just before processing an order (rejecting an order if not yet ready to be processed is actually a business invariant hence should be explicitly presented).
Is it possible to create a factory? if so how do you add items making
the order methods private (since no one can add items without it being
through the factory)?
A factory hides implementation details related to the way an entity is being constructed. Associating an order-item to an order is not part of constructing an order, so a factory cannot be the solution; the two methods should remain public.

c# WPF - Custom UserControl with a List as DependencyProperty [duplicate]

I have lots of entities with nested List<> in each.
For example, I have BaseEntity which has List<ColumnEntity>.
ColumnEntity class has List<Info> and so on.
We are working with a WPF UI, and we need to track all changes in every List of BaseEntity. It is implemented by instantiating a new ObservableCollection based on the needed list, and with binding to that ObservableCollection.
What are the pros and cons changing all these nested Lists to ObservableCollections? So we can track all changes in BaseEntity itself without reassigning each list of BaseEntity to modified bound ObservableCollection?
Assuming that methods specific to List are never used.
Interesting question, considering that both List and ObservableCollection implement IList<T> there isn't much of a difference there, ObservableCollection also implements INotifyCollectionChanged interface, which allows WPF to bind to it.
One of the main differences is that ObservableCollection does not have AddRange method, which might have some implications.
Also, I would not use ObservableCollection for places where I know I would not be binding to, for this reason, it is important to go over your design and make sure that you are taking the correct approach in separating layers of concern.
As far as the differences between Collection<T> and List<T> you can have a look here
Generic Lists vs Collection
It depends on exactly what you mean by this:
we need to track all changes in every List of BaseEntity
Would it be enough to track changes to objects already in the list? Or do you need to know when objects are removed from/are added to/change positions within the list?
If a list will contain the same items for their whole lifetime, but the individual objects within that list will change, then it's enough for just the objects to raise change notifications (typically through INotifyPropertyChanged) and List<T> is sufficient. But if the list will contain different objects from time to time, or if the order changes, then you should use ObservableCollection<T>.
So while the differences may be interesting (and a previous poster has already covered those), typically you won't have that much of a choice - either you need ObservableCollection<T> or you don't.
List represents a strongly typed list of objects that can be accessed by index. It provides methods to search, sort, and manipulate lists. The List class is the generic equivalent of the ArrayList class. It implements the IList generic interface using an array whose size is dynamically increased as required.
ObservableCollection is a generic dynamic data collection that uses an interface "INotifyCollectionChanged" to provide notifications when items get added, removed, or when the whole collection is refreshed.
Read more about it in this link: http://www.codeproject.com/Articles/42536/List-vs-ObservableCollection-vs-INotifyPropertyCha
One more important difference is you can access ObservableCollection only from thread on which it was created where as list can be accessed fromany thread.
I see no problem with that, other than a very marginal performance overhead.
Note that if you modify the internal Lists directly, you are not notified about changes. Also if the objects which are contained in the ObservableCollection are modified you are not notified. Notification occurs only, if elements are added, replaced, removed or moved.

Is there a type of unordered collection in .NET which can add and remove objects quickly?

So I have a special class which can remove itself from a collection, let's say it looks something like this:
public class FunTimes{
public ICollection<FunTimes> Collection {get;set;}
protected void RemoveFromCollection(){
Collection.Remove(this);
}
}
RemoveFromCollection() will be called from an event. I want the collection to add and remove items quickly, and since position doesn't matter in my case, I planned to use something other than a List<T>. I can't really use a ConcurrentBag<T>, since I have to iterate over every item to remove an item. I've finally decided to use a Dictionary<FunTimes, FunTimes>, and then use each FunTimes instance as both the key AND the value. I'm asking if there's a better solution because using an object as both the key and the value in a Dictionary just seems plain weird. Any suggestions?
If Dictionary<FunTimes, FunTimes> satisfies your needs better option would be using HashSet<T> which should have O(1) addition and removal.

Custom collection that is observable-self sorting-prevents insertions etc

I have a custom type that knows how to compare with others (it implements IComparable), it is working great stored inside an ObservableList.
However there is still somethings lacking in the collection. I am in need of 4 features. A collection that :
Detects duplicates and prevents insertions.
Automatically sorts on every successful insert.
Is observable &
If batches of items are inserted only notifies once the batch is
inserted.
I would like tips on how to make such a collection, what I will need to research/implement etc. I am not looking for code but if you can give that its a bonus.
What I have thought about doing :
Inheriting from ObservableCollection, overriding the add method, checking if the item already exists, if it does ignoring it.
Or
Implementing my own observable collection based off a more generic type like List.
Since you you want to prevent duplicate insertions and you want sorting, a SortedSet might be a good starting position. Since you want notifications, you'll have to extend the standard SortedSet and implement INotifyCollectionChanged and INotifyPropertyChanged. There's an example here and another one here which uses a HashSet instead (which is unordered, but you can easily replace with a SortedSet).
The alternative, which is just as valid, is to go with you first suggestion and extend ObservableCollection.

ConfigurationManager.GetSection Skips Duplicates

Long story short, the .Net ConfigurationManager.GetSection method skips duplicates, and I'm looking for a best practice for handling this. I have a config file that includes something like this:
<views>
<view name="BusinessUnitsView" Desc="desc1"/>
<view name="BusinessUnitsView" Desc="desc2"/>
</views>
I have a graph of objects the config loads onto where collections derive from our derived version of ConfigurationElementCollection. The views collection in the graph only has one item in it after loading the above--my understanding is that this is simply the way the ConfigurationManager handled duplicates. The last item with the same key wins.
I could throw an exception on a duplicate being found by using BaseAdd(element, true). However, if possible I'd like to get the object completely loaded WITH duplicates, as the config gets read in a service layer, and I'd like to detect and deal with the problem on the consuming side of the service.
Do I have any options for modifying the way adds to the collection work?
You will need to create your own ConfigurationSection. See here or here (the second link's method has been deprecated, but it may still shed some light)
This allows you to represent internal configuration variables as collections, and set properties like DefaultValue and IsRequired.
Maybe you only want to iterate over a list but the main idea of the config is that you can do
var view = SomeConfigClass["BusinessUnitsView"];
That only allows one answer.

Categories