You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Right now, all of the ways that IPropertyHandler implementations can be defined is hard-coded into the static constructor of ImmutableBase<TImmutable>. This sucks for two big reasons:
If someone wants to add a custom IPropertyHandler implementation, the have to do it with hackery and reflection. It is essentially non-extensible.
Create an AggregatePropertyHandlerProvider that takes in a list of IPropertyHandlerProvider implementations and processes them in order. The first match is used to create an IPropertyHandler.
Use a IPropertyHandlerFactory in the ImmutableBase<TImmutable> static constructor to hydrate IPropertyHandler implementations instead of doing it all in a hard-coded fashion as it does today. It should have a public getter and setter such that others can change how properties are cached. Additionally, when it changes its value, that should cause all of the cached IPropertyHandler implementations to be rebuilt using the new IPropertyHandlerFactory.
Assuming all of these changes went through, I would expect the static constructor for ImmutableBase<TImmutable> to start to look something like this:
publicstaticIPropertyHandlerFactoryPropertyHandlerFactory{get{returnhandlerFactory;}set{handlerFactory=value;ClearHandlersCache();}}staticImmutableBase(){handlerFactory=newAggregatePropertyHandlerProvider(newStringPropertyHandlerProvider(),newEnumerablePropertyHandlerProvider(),newDefaultPropertyHandlerProvider());// ... other initialization code.}
Then, when we implement #12 and #14, we can keep that logic in the IPropertyHandlerProvider implementations instead of keeping it centrally located in the ImmutableBase<TImmutable> static constructor.
Background
Right now, all of the ways that
IPropertyHandlerimplementations can be defined is hard-coded into the static constructor ofImmutableBase<TImmutable>. This sucks for two big reasons:IPropertyHandlerimplementation, the have to do it with hackery and reflection. It is essentially non-extensible.IPropertyHandleris to be constructed (like, for example, as defined in Add [StringComparison]-like annotation for String properties #12 and Add [EnumerableComparison]-like annotation for IEnumerable properties #14), that logic gets stuck inside ofImmutableBase<TImmutable>when it could have its complexity compartmentalized.Both of these could be solved with a few interfaces with default implementations.
Task
Create two new interfaces, as follows:
Create three implementations,
StringPropertyHandlerProvider,EnumerablePropertyHandlerProvider(for Set & List) andDefaultPropertyHandlerProvider, that inspect the relevantPropertyInfoas we do inImmutableBase<TImmutable>static constructor today to determine support and desired approach to hydration.Create an
AggregatePropertyHandlerProviderthat takes in a list ofIPropertyHandlerProviderimplementations and processes them in order. The first match is used to create anIPropertyHandler.Use a
IPropertyHandlerFactoryin theImmutableBase<TImmutable>static constructor to hydrateIPropertyHandlerimplementations instead of doing it all in a hard-coded fashion as it does today. It should have a public getter and setter such that others can change how properties are cached. Additionally, when it changes its value, that should cause all of the cachedIPropertyHandlerimplementations to be rebuilt using the newIPropertyHandlerFactory.Assuming all of these changes went through, I would expect the static constructor for
ImmutableBase<TImmutable>to start to look something like this:Then, when we implement #12 and #14, we can keep that logic in the
IPropertyHandlerProviderimplementations instead of keeping it centrally located in theImmutableBase<TImmutable>static constructor.