Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IPropertyHandlerProvider concept to allow for custom property handling #45

Closed
4 tasks done
carusology opened this issue Feb 23, 2018 · 0 comments
Closed
4 tasks done

Comments

@carusology
Copy link
Contributor

carusology commented Feb 23, 2018

Background

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:

  1. If someone wants to add a custom IPropertyHandler implementation, the have to do it with hackery and reflection. It is essentially non-extensible.
  2. If we add any complexity on how an IPropertyHandler is 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 of ImmutableBase<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:

    public interface IPropertyHandlerFactory {
        IPropertyHandler Create(PropertyInfo property);
    }
    
    public interface IPropertyHandlerProvider : IPropertyHandlerFactory {
        bool IsSupported(PropertyInfo propertyInfo);
    }
  • Create three implementations, StringPropertyHandlerProvider, EnumerablePropertyHandlerProvider (for Set & List) and DefaultPropertyHandlerProvider, that inspect the relevant PropertyInfo as we do in ImmutableBase<TImmutable> static constructor today to determine support and desired approach to hydration.

  • 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:

public static IPropertyHandlerFactory PropertyHandlerFactory { 
    get { return handlerFactory; }
    set { handlerFactory = value; ClearHandlersCache(); }
}

static ImmutableBase() {
    handlerFactory = new AggregatePropertyHandlerProvider(
        new StringPropertyHandlerProvider(),
        new EnumerablePropertyHandlerProvider(),
        new DefaultPropertyHandlerProvider()
    );

    // ... 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.

@carusology carusology changed the title Add IPropertyHandlerProvider concept to extend property handling Add IPropertyHandlerProvider concept to allow for custom property handling Feb 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant