How Do I Use Profiles?¶
Define one¶
public sealed class ApplicationTestProfile : ICompositionProfile
{
public void Configure(CompositionBuilder builder) =>
builder
.UseNSubstitute()
.UseBogus()
.Register<IClock>(_ => new FakeClock());
}
Apply it programmatically¶
Apply it to a composed xUnit theory¶
[Theory]
[Compose<ApplicationTestProfile>]
public void ComposesTheProfileConfiguredValue(NotificationSettings settings) { }
TProfile must implement ICompositionProfile and have a public parameterless constructor — [Compose<TProfile>] enforces this at compile time via a generic constraint.
Combining more than one profile¶
var composer = Composer.Create(builder => builder
.AddProfile<DomainProfile>()
.AddProfile<InfrastructureProfile>());
Profiles apply in the order added. Build up project-wide configuration from a few small, focused profiles rather than one large one — it's easier to reuse a DomainProfile on its own in a test that doesn't need InfrastructureProfile's configuration.
Applying an already-built instance instead of a type¶
Use this over AddProfile<TProfile>() only when the profile itself needs constructor arguments — most profiles don't, and AddProfile<TProfile>() is the more common form.
Common mistakes¶
- A profile that applies itself again while already applying (directly, or through a nested profile) — this is a cycle, raised immediately as
CompositionConfigurationException, not a silently-ignored no-op. - Putting per-test assertions or mutable state inside a profile — a profile is pure
Composerconfiguration, applied once, synchronously.
Next¶
- What a profile is and when to reach for one → Profiles.
- Using a profile from
Compono.XunitV3specifically →Compono.XunitV3Package Guide. - Registering an individual type instead → Register a Type.