VSMEF006 Import nullability and AllowDefault mismatch
When using nullable reference types, the nullability of an import should match its AllowDefault setting. This analyzer detects mismatches between nullable annotations and the AllowDefault property in import attributes.
Two types of mismatches detected
1. Nullable import without AllowDefault = true
The following property definition would produce a diagnostic from this rule:
#nullable enable
using System.ComponentModel.Composition;
class Foo
{
[Import]
public string? SomeProperty { get; set; }
}
This property is nullable (can accept null values) but doesn't have AllowDefault = true, which means MEF will throw an exception if no matching export is found instead of setting the property to null.
Fix the diagnostic by adding AllowDefault = true:
#nullable enable
using System.ComponentModel.Composition;
class Foo
{
[Import(AllowDefault = true)]
public string? SomeProperty { get; set; }
}
2. AllowDefault = true without nullable type
The following property definition would also produce a diagnostic:
#nullable enable
using System.ComponentModel.Composition;
class Foo
{
[Import(AllowDefault = true)]
public string SomeProperty { get; set; }
}
This property has AllowDefault = true (meaning it can be null if no export is found) but is declared as non-nullable, creating a potential null reference exception.
Fixing the diagnostic
Option 1: Make the type nullable
#nullable enable
using System.ComponentModel.Composition;
class Foo
{
[Import(AllowDefault = true)]
public string? SomeProperty { get; set; }
}
Option 2: Remove AllowDefault
#nullable enable
using System.ComponentModel.Composition;
class Foo
{
[Import]
public string SomeProperty { get; set; }
}
Additional examples
Constructor parameters
The same rules apply to constructor parameters:
#nullable enable
using System.ComponentModel.Composition;
[Export]
class Foo
{
[ImportingConstructor]
public Foo([Import(AllowDefault = true)] string? optionalService)
{
// optionalService can be null
}
}
ImportMany with nullable collections
For ImportMany, the collection itself typically shouldn't be nullable, but the element type might be:
#nullable enable
using System.ComponentModel.Composition;
class Foo
{
[ImportMany]
public IEnumerable<IService?> Services { get; set; } = null!;
}
Benefits
Following this analyzer's recommendations helps ensure:
- Consistency: Nullable annotations accurately reflect the runtime behavior
- Safety: Reduces null reference exceptions at runtime
- Clarity: Makes the intent clear to other developers reading the code
- Tooling support: Enables better IntelliSense and static analysis