2
\$\begingroup\$

Can I somehow refactor this into one class? Some things are common here like Metadata property.

public class Resource<TEntity>
{
    public TEntity Data { get; set; }

    public Dictionary<string, string> Metadata { get; set; }

    public Resource(TEntity data)
    {
        Data = data;
    }
}

public class ResourceCollection<TEntity>
{
    public ICollection<TEntity> Data { get; set; }

    public Dictionary<string, string> Metadata { get; set; }

    public int Count { get; set; }

    public ResourceCollection(ICollection<TEntity> data)
    {
        Data = data;

        Count = data.Count;
    }
}

Is this possible to make interface that expects either ICollection<TEntity> or TEntity alone?

This wrapper class is used for serialization it simply acts as a wrapper, but still I have some doubts about it that it could be done better

I also came up with this:

public class Resource<T>
{
    public T Data { get; set; }

    [JsonExtensionData]
    public Dictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();

    public Resource(T data)
    {
        Data = data;

        if (data is ICollection collection)
        {
            Metadata["count"] = collection.Count;
        }
    }
}
\$\endgroup\$
13
  • 2
    \$\begingroup\$ Why can't you just use the first class? What is the benefit of using ResourceCollection<Foo> over Resource<List<Foo>>? (I'm not implying that there is no reason to do so, but I assume that you've omitted the code that would answer these questions). For CodeReview.SE, you should really be posting the full code, including usage (and and explanation of what you hope to achieve with the code) \$\endgroup\$
    – Flater
    Commented May 17, 2018 at 9:28
  • 1
    \$\begingroup\$ But that doesn't make sense. What would the Count of a resource be when it's not an IEnumerable? Fixed value 1? If you're asking to unify these classes, then you're obviously going to have a Count for all cases (whether it's a collection or not). You seem to be focusing on how to do it, but you still haven't actually shown a justification for why you need to do it, which should be the first step here. \$\endgroup\$
    – Flater
    Commented May 17, 2018 at 9:36
  • 2
    \$\begingroup\$ Given the updated code, what is the actual question you're asking here? It seems like you've already answered your own question, no? \$\endgroup\$
    – Flater
    Commented May 17, 2018 at 9:41
  • 1
    \$\begingroup\$ Happy to be your rubber duck! ;) \$\endgroup\$
    – Flater
    Commented May 17, 2018 at 9:44
  • 1
    \$\begingroup\$ One thing that looks problematic is that all properties are publicly settable. Are you sure you want to allow any code to do rc.Metadata = null? And why do you need a Count property if you already have an ICollection? If you do need it, why doesn't it just return Data.Count, as Nikita's answer does? \$\endgroup\$ Commented May 17, 2018 at 13:42

1 Answer 1

4
\$\begingroup\$

I guess you could use inheritance if you really need that extra property:

public class ResourceCollection<TEntity> : Resource<ICollection<TEntity>>
{
    public ResourceCollection(ICollection<TEntity> data) : base(data)
    {
        //modify metadata if needed
    }

    public int Count => Data.Count;
}

While technically this is still two classes, you can now cast your collections to Resource<T> and process them in generic manner with your other resources.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.