Reputation: 169
I have a custom service which in that I'm using Microsoft's IDataProtector
.
I have registered my service in startup with AddScoped
but i have a problem with using IDataProtector
.
error message:
Unable to resolve service for type 'Microsoft.AspNetCore.DataProtection.IDataProtector' while attempting to activate 'Service'.
here is my code :
public class Service: IInjectable
{
private readonly IDataProtector _protector;
public Service(IDataProtector protector)
{
_protector = protector.CreateProtector("key");
}
other code ...
}
The way I have registered my service:
public static void RegisterScoped<T>(
this IServiceCollection services, params Assembly[] assemblies)
{
IEnumerable<Type> types = assemblies.SelectMany(a => a.GetExportedTypes())
.Where(c => c.IsClass && typeof(T).IsAssignableFrom(c));
foreach (var item in types)
services.AddScoped(item);
}
StartUp :
services.RegisterScoped<IInjectable>(typeof(IInjectable).Assembly);
Upvotes: 4
Views: 7238
Reputation: 2448
I run into the same situation one day as well and had to go through source code of class method AddDataProtection()
of class DataProtectionServiceCollectionExtensions
in assembly Microsoft.AspNetCore.DataProtection.dll
.
For those who is interested in details how registration of DataProtection service happens this is extract of code where actual magic happens:
private static void AddDataProtectionServices(IServiceCollection services)
{
if (OSVersionUtil.IsWindows())
{
// Assertion for platform compat analyzer
Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
services.TryAddSingleton<IRegistryPolicyResolver, RegistryPolicyResolver>();
}
services.TryAddEnumerable(
ServiceDescriptor.Singleton<IConfigureOptions<KeyManagementOptions>, KeyManagementOptionsSetup>());
services.TryAddEnumerable(
ServiceDescriptor.Singleton<IPostConfigureOptions<KeyManagementOptions>, KeyManagementOptionsPostSetup>());
services.TryAddEnumerable(
ServiceDescriptor.Transient<IConfigureOptions<DataProtectionOptions>, DataProtectionOptionsSetup>());
services.TryAddSingleton<IKeyManager, XmlKeyManager>();
services.TryAddSingleton<IApplicationDiscriminator, HostingApplicationDiscriminator>();
services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService, DataProtectionHostedService>());
// Internal services
services.TryAddSingleton<IDefaultKeyResolver, DefaultKeyResolver>();
services.TryAddSingleton<IKeyRingProvider, KeyRingProvider>();
services.TryAddSingleton<IDataProtectionProvider>(s =>
{
var dpOptions = s.GetRequiredService<IOptions<DataProtectionOptions>>();
var keyRingProvider = s.GetRequiredService<IKeyRingProvider>();
var loggerFactory = s.GetService<ILoggerFactory>() ?? NullLoggerFactory.Instance;
IDataProtectionProvider dataProtectionProvider = new KeyRingBasedDataProtectionProvider(keyRingProvider, loggerFactory);
// Link the provider to the supplied discriminator
if (!string.IsNullOrEmpty(dpOptions.Value.ApplicationDiscriminator))
{
dataProtectionProvider = dataProtectionProvider.CreateProtector(dpOptions.Value.ApplicationDiscriminator);
}
return dataProtectionProvider;
});
services.TryAddSingleton<ICertificateResolver, CertificateResolver>();
}
As you can see here, only IDataProtectionProvider
registered in line services.TryAddSingleton<IDataProtectionProvider>
and nothing mentions IDataProtector
.
Upvotes: 2
Reputation: 169
Finally , i found the problem :
i had to use IDataProtectionProvider instead of IDataProtector in my service constructor
Upvotes: 12