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.
@moodmosaic You bring up two very valid points. I'm going to address them separately.

#### Part 1

> IMHO fluent interfaces that evolve together with their underlying object model can be problematic if the underlying object model is not yet complete or has to be changed

In general, I tend to agree on that point. However, given what AutoFixture does for a living, I think there's a pretty *limited* set of things you can match on. Type variance and member/parameter identifiers pretty much cover most scenarios.
Should the need arise to add a new kind of matching, extending the interface isn't a problem, since it's not meant for external implementers and there's only one single internal implementation to maintain.

In my opinion, the stable set of structures the interface operates on and the friendliness it brings to the user, both outweigh its maintenance burden.

#### Part 2 

> the fluent interface can make the Customize<T> syntax easier for experienced AutoFixture users – still there are users (e.g. on Stack Overflow) new to AutoFixture that find Customize<T> confusing as-is

Here's where things get a little philosophical :wink: Anyway, here's how I see it.

When designing APIs, I like to follow the principle, well stated by Alan Kay, that says:

> Simple things should be simple, complex things should be possible.

In order to achieve this, an API exposes some *high level* abstractions that are specifically designed to make the most common tasks intuitive and easily accessible.
In AutoFixture, these high level concepts are the `Fixture`, the *customizations* (both in the form of the customization API as well as the `ICustomization` interface) and the *auto data* attributes.

These high level abstractions are, in turn, built on top of some *lower level* constructs that carry out the actual work. Here, in AutoFixture terms, we're talking about things like `ISpecimenBuilder`, `ISpecimenCommand` and `IRequestSpecification`.

The lower level abstractions are not designed to be intuitive to an external consumer nor easy to use, but rather to represent the inner structure of the system in a way that makes sense for whoever is working on it.
They *can*, however, be directly manipulated from the outside and are something the user can *fall back on* to achieve the more complex scenarios not directly supported in the high level API.

In my opinion, the Matching API brings a simple and fairly common scenario like matching anonymous values based on different criteria up to the "user friendly" high level API, while in the past it used to require interaction with the lower level constructs.

Here's a concrete example taken from @ploeh's [post about building conventions in AutoFixture](http://blog.ploeh.dk/2010/10/19/Convention-basedCustomizationswithAutoFixture/).

In order to assign a valid currency code to all string parameters named "*currencyCode*", one would have to implement a custom `ISpecimenBuilder` and check for the right kind of requests:

```csharp
public class CurrencyCodeSpecimenBuilder : ISpecimenBuilder
{
    public object Create(object request, ISpecimenContext context)
    {
        var pi = request as ParameterInfo;

        if (pi == null)
        {
            return new NoSpecimen(request);
        }

        if (pi.ParameterType != typeof(string)
            || pi.Name != "currencyCode")
        {
            return new NoSpecimen(request);
        }
 
        return "DKK";
    }
}
```

Even if we're all very familiar with the concepts mentioned in that class (*specimen*, *request*, *specimen context*, *no specimen*) I'm pretty sure that they're completely foreign to most people who are approaching AutoFixture for the first time. And rightly so, since they belong to the realm of lower level abstractions.
In addition, this approach also requires having to deal directly with Reflection types.

Compare that with a customization that uses the Matching API:

```csharp
fixture.Customize<string>(c => c
       .FromFactory(() => "DKK")
       .Match().ByParameter("currencyCode"));
```

I can't count how many times I've wished I could simply write these kinds of customizations without having to first having to make custom builders, request specifications and so on.

In conclusion, I think the Matching API makes a simple thing easy to do, both for advanced users as well as for beginners.