Skip to content

Allow extending genericInterfaceImplementations of DefaultObjectFactory #982

Closed

Description

@n9

Is your feature request related to a problem? Please describe.

It seems to me that there is currently no way to extend defaultGenericInterfaceImplementations of DefaultObjectFactory.

private readonly Dictionary<Type, Type> defaultGenericInterfaceImplementations = new()
{
{ typeof(IEnumerable<>), typeof(List<>) },
{ typeof(ICollection<>), typeof(List<>) },
{ typeof(IList<>), typeof(List<>) },
{ typeof(IDictionary<,>), typeof(Dictionary<,>) }
};

Mappings are only added to defaultNonGenericInterfaceImplementations.

foreach (var pair in mappings)
{
if (!pair.Key.IsAssignableFrom(pair.Value))
{
throw new InvalidOperationException($"Type '{pair.Value}' does not implement type '{pair.Key}'.");
}
defaultNonGenericInterfaceImplementations.Add(pair.Key, pair.Value);
}

Describe the solution you'd like

Provide a "simple" way to extend defaultGenericInterfaceImplementations.

Describe alternatives you've considered

Modify copy of DefaultObjectFactory.

Additional context

N/A

Activity

  1. changed the title [-]Allow to specify genericInterfaceImplementations for DefaultObjectFactory[/-] [+]Allow extending genericInterfaceImplementations of DefaultObjectFactory[/+] on Sep 25, 2024
  2. EdwardCooke commented on Sep 25, 2024

    @EdwardCooke
    Collaborator

    How are you wanting to extend that class? If you're wanting to add additional types you can do that by passing in a dictionary of type mappings. That linked method is just making sure the types are assignable and making a copy of the passed in dictionary. We could remove the sealed part of the class so you could extend it, that wouldn't be hard at all.

  3. n9 commented on Sep 26, 2024

    @n9
    Author

    Yes, that will be sufficient.

    Moreover, I realized that in my case extending defaultGenericInterfaceImplementations does not help, I need to create an INodeTypeResolver (as suggested here #236 (comment)).

    But for mapping-like collections, I also need to tweak the serialization (mentioned here #236 (comment)). Currently, I do the following:

    static readonly IObjectFactory objectFactoryForSerialization = new CustomObjectFactoryForSerialization();
    
    ...
    
    .WithObjectGraphTraversalStrategyFactory((typeInspector, typeResolver, typeConverters, maximumRecursion) =>
        new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, CamelCaseNamingConvention.Instance, objectFactoryForSerialization))

    Where CustomObjectFactoryForSerialization is this:

    public class CustomObjectFactoryForSerialization : ObjectFactoryBase
    {
        public override bool GetDictionary(IObjectDescriptor descriptor, out IDictionary? dictionary, out Type[]? genericArguments)
        {
            genericArguments = descriptor.Type.GetInterfaceGenericArguments(typeof(IReadOnlyDictionary<,>));
            if (genericArguments != null)
            {
                dictionary = (IDictionary)Activator.CreateInstance(typeof(ReadOnlyDictionaryAdapter<,>).MakeGenericType(genericArguments), descriptor.Value)!;
                return true;
            }
            return base.GetDictionary(descriptor, out dictionary, out genericArguments);
        }
    
        public override object Create(Type type) => throw new NotSupportedException();
    }

    Since I cannot currently derive from DefaultObjectFactory.

    Removing sealed from DefaultObjectFactory will also help in this case, I would be able to derive from DefaultObjectFactory instead of ObjectFactoryBase.

  4. EdwardCooke commented on Sep 26, 2024

    @EdwardCooke
    Collaborator

    Sounds good, it'll be done.

  5. added a commit that references this issue on Sep 26, 2024
    27c995c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions