{"record":{"id":"7a107a4aee3f03e4","repo":"OrchardCMS/OrchardCore","slug":"the-type-must-implement-the-iemailprovider-interface","errorCode":null,"errorMessage":"The type must implement the 'IEmailProvider' interface.","messagePattern":"The type must implement the 'IEmailProvider' interface\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.Email.Core/Services/EmailProviderTypeOptions.cs","lineNumber":11,"sourceCode":"namespace OrchardCore.Email.Services;\n\npublic class EmailProviderTypeOptions\n{\n    public Type Type { get; }\n\n    public EmailProviderTypeOptions(Type type)\n    {\n        if (!typeof(IEmailProvider).IsAssignableFrom(type))\n        {\n            throw new ArgumentException($\"The type must implement the '{nameof(IEmailProvider)}' interface.\");\n        }\n\n        Type = type;\n    }\n\n    public bool IsEnabled { get; set; }\n}\n","sourceCodeStart":1,"sourceCodeEnd":19,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.Email.Core/Services/EmailProviderTypeOptions.cs#L1-L19","documentation":"EmailProviderTypeOptions wraps a provider implementation Type and validates at construction that the type implements IEmailProvider. Passing any other type is rejected immediately with this ArgumentException, keeping provider registration type-safe.","triggerScenarios":"Registering an email provider with `new EmailProviderTypeOptions(typeof(SomeService))` where SomeService does not implement IEmailProvider; configuring EmailProviderOptions.Providers dictionary with a wrong or renamed type.","commonSituations":"Typo or wrong type passed during AddEmailProvider/options configuration; a custom provider class refactored away from IEmailProvider but still referenced in options setup; DI startup code copied from another module without updating the type.","solutions":["Make the registered type implement IEmailProvider (and IAsyncDisposable if needed)","Fix the type reference in the options setup so it points at the intended provider class","Add a startup-time assertion/test that all configured provider types implement IEmailProvider"],"exampleFix":"// before\nservices.Configure<EmailProviderOptions>(o => o.Providers[\"smtp\"] = new EmailProviderTypeOptions(typeof(SmtpService)));\n// after\npublic sealed class SmtpEmailProvider : IEmailProvider { ... }\nservices.Configure<EmailProviderOptions>(o => o.Providers[\"smtp\"] = new EmailProviderTypeOptions(typeof(SmtpEmailProvider)));","handlingStrategy":"validation","validationCode":"if (!typeof(IEmailProvider).IsAssignableFrom(providerType))\n    throw new ArgumentException($\"{providerType} must implement IEmailProvider before registration\");","typeGuard":"bool IsValidProviderType(Type t) => t is not null && typeof(IEmailProvider).IsAssignableFrom(t);","tryCatchPattern":"try { options.Providers[name] = new EmailProviderTypeOptions(type); } catch (ArgumentException ex) { _logger.LogCritical(ex, \"Bad email provider registration for {Name}\", name); throw; }","preventionTips":["Register providers only through helper extension methods that enforce the interface","Keep one class per provider implementing IEmailProvider","Add a startup test asserting all configured provider types implement IEmailProvider"],"tags":["email","dependency-injection","type-safety","configuration"],"backgroundTag":"invalid-argument-value","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}