AutoFixture/AutoFixture — pull request #120 by ecampidoglio (2014-09-04 11:53:40+00:00)
Title: MatchOn property for [Frozen] attribute

Currently, the `[Frozen]` attribute (in the *AutoFixture.Xunit* package) freezes the type of the method argument it's applied to. For example

```c#
[Theory, AutoData]
public void MyTestMethod([Frozen]Foo foo, Bar sut)
{
// Test goes here...
}
```

the `Foo` type would be frozen, which means that no matter how many instances of `Foo` created within this test case, the same instance would always be used.

It would be more flexible if the `[Frozen]` attribute had a `MatchOn` property, where the user could specify which sort of match to use; e.g.

```c#
[Theory, AutoData]
public void MyTestMethod([Frozen(MatchOn = Matches.ArgumentName)]Foo foo, Bar sut)
{
// Test goes here...
}
```

which would mean that instead of matching on the type `Foo`, the `[Frozen]` attribute would match on the `foo` name. In this case, it would match any other `ParameterInfo` called `foo`.

This would enable scenarios where you'd want to test a class with this type of constructor:

```c#
public class Bar
{
public Bar(Foo foo, Foo otherFoo) { }
}
```

By writing the above test, `Matches.ArgumentName` would ensue that only requests for a `ParameterInfo` called `foo` would be frozen. In other words, this would mean that the `Bar` instance would get the same instance for its `foo` constructor argument as the test gets its `foo` method argument, but the `otherFoo` constructor argument would be different.

I think that perhaps, this could also be used to deprecate the current `As` property, because instead, one could write something like:

```c#
[Theory, AutoData]
public void MyOtherTestMethod(
[Frozen(MatchOn = Matches.ImplementedInterfaces)]Baz baz,
Qux sut)
{
// Test goes here...
}
```

Now, if `Baz` implements `IBaz` the `[Frozen]` attribute would also apply to `IBaz`, and so if the SUT's constructor is `public Qux(IBaz whatever)`, the `baz` test method parameter would still be matched to the `whatever` constructor argument.

It seems to me that `Matches` should be a `[Flags]` enum; something like:

```c#
[Flags]
public enum Matches
{
Type = 0,
ImplementedInterfaces = 1,
BaseClass = 2,
ArgumentName = 4,
PropertyName = 8,
FieldName = 16,
MemberName = ArgumentName | PropertyName | FieldName
}
```

etc. There may be more.

The only reason to have an enum is to enable configuration of an attribute. The enum should as soon as possible be translated into an appropriate `OrRequestSpecification`.

This issue is a border-line [jump-in](http://nikcodes.com/2013/05/10/new-contributor-jump-in/) issue. The reason why the description is so long is not because it would be very complicated to implement (I think), but because I wanted to provide as much detail as possible. Still, if you decide to pick up this one and you have questions, feel free to ask.