Consider the following architecture designed for logging operations Add/Update that are being done on an instance of Entity.
LogFactory is an Abstract Factory and receives two factories for Add and Update via constructor using DI.
Both concrete factories AddLogFactory and UpdateLogFactory implement ILogFactory in order to produce an ILog. They both need an Entity to collect log-able data.
Well, I hope everything is clear and you admit Abstract Factory pattern is the right solution so far.

Problem:
UpdateLogFactory is an exception because it needs additional data: ModifiedProperties to create a before/after string (meanwhile its siblings i.e. other types implementing ILogFactory don't need this kind of data; an Entity suffices them). In order to not break the ILogFactory, I decided to give ModifiedProperties to UpdateLogFactory via its constructor.
It solves my problem but I feel I'm cheating somehow; I'm pretending UpdateLogFactory is similar to others while it is actually not.
If someone wants to replace UpdateLogFactory with another concrete type how does he know it needs ModifiedProperties?
Actually
ModifiedPropertiesis an implementation detail. Do anyILogFactoryneed to produce that before and after format? I don't think so.Anyway, I believe that
ModifiedPropertiesshouldn't be injected but they should be part of an interface likeICanTrackPropertyChanges:And
ICanTrackPropertyChangesshould be implemented by your entities. Thus,UpdateLogFactorycan make the following assertion:This way, you don't need to provide
ModifiedPropertiesas an implementation detail ofILogFactory, but you believe that entities can track property changes if they implement an interface.You can enforce this using generic constraints:
...and use this interface to implement loggeable entity updates.
In addition, you get an improvement:
IUpdateLogFactory<TEntity>implementations won't need to check if an entity hasModifiedPropertybecause handled entities are guaranteed to has the wholeIEnumerable<string>of modified properties at compile time!