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

ConcurrentDictionary #1176

Open
JoshKeegan opened this issue Apr 24, 2020 · 6 comments
Open

ConcurrentDictionary #1176

JoshKeegan opened this issue Apr 24, 2020 · 6 comments
Labels
feature request An idea for a change, aimed at impoving quality of life
Milestone

Comments

@JoshKeegan
Copy link

Hi,
When I use autofixture to generate a Dictionary<T, U> I get values populated in it by default, but with a ConcurrentDictionary<T, U> I don't.

Is this by design & I should use a specimen builder to alter that behaviour myself, or is it a missing feature or bug?

@JoshKeegan
Copy link
Author

JoshKeegan commented Apr 24, 2020

If anyone else comes accross the same issue, I've written a specimen builder for this:

public class ConcurrentDictionaryGenerator : ISpecimenBuilder
{
	public object Create(object request, ISpecimenContext context)
	{
		Type type = request as Type;
		if (type == null)
		{
			return new NoSpecimen();
		}

		Type[] typeArguments = type.GetTypeInfo().GetGenericArguments();
		if (typeArguments.Length != 2 || typeof(ConcurrentDictionary<,>).MakeGenericType(typeArguments) != type)
		{
			return new NoSpecimen();
		}

		Type nonConcurrentDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeArguments);
		IDictionary nonConcurrentDictionary = (IDictionary) context.Resolve(nonConcurrentDictionaryType);

		IDictionary concurrentDictionary = (IDictionary) Activator.CreateInstance(type);

		foreach (object key in nonConcurrentDictionary.Keys)
		{
			object value = nonConcurrentDictionary[key];
			concurrentDictionary.Add(key, value);
		}

		return concurrentDictionary;
	}
}

@Ergamon
Copy link

Ergamon commented Apr 27, 2020

Hello,
I cannot tell the reasons behind this, but it looking at the source code the supported collections are hard coded.
So it is not something like "does type implement IDictionary", it is "is type Dictionary<,>". Therefore ConcurrentDictionary does not work.
You dont need to create your own specimenbuilder, you can use what is already there:

      var fixture = new Fixture();

      var query = new ModestConstructorQuery();
      var methodInvoker = new MethodInvoker(query);
      var dictionaryFiller = new DictionaryFiller();
      var postProcessor = new Postprocessor(methodInvoker, dictionaryFiller);
      var exactTypeSpecification = new ExactTypeSpecification(typeof(ConcurrentDictionary<,>));
      var specimenBuilder = new FilteringSpecimenBuilder(postProcessor, exactTypeSpecification);

      fixture.Customizations.Add(specimenBuilder);

@Kralizek
Copy link
Contributor

The more I learn about the internals of this library, the more I love it

@JoshKeegan
Copy link
Author

Interesting to know it's only on Dictionary<,> currently & thanks for the built-in way of doing it!

I guess the only remaining question for someone would then be: would this be a good feature to add? Perhaps not for ConcurrentDictionary<,> specifically, but all IDictionary<,> implementations?

@Ergamon
Copy link

Ergamon commented Apr 27, 2020

Just that I dont spread wrong information, it is is not only Dictionary<,>. I just wanted to point out that the list of types can be found directly in Fixture.cs. E.g. it is also SortedDictionary<,>, but as you already figured out, it is not ConcurrentDictionary<,>.
By all means I would say that a future implementation should check for the interface.

@Kralizek
Copy link
Contributor

In reality what's hardcoded it's not the support rather the fact that interfaces are relayed to some concrete type. Like IDictionary and IReadOnlyDictionary are relayed to Dictionary, and so on.

@aivascu aivascu added this to the v4.0 milestone Dec 5, 2023
@aivascu aivascu added the feature request An idea for a change, aimed at impoving quality of life label Dec 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request An idea for a change, aimed at impoving quality of life
Projects
None yet
Development

No branches or pull requests

4 participants