diff --git a/src/Microsoft.AspNetCore.DataProtection.Redis/Microsoft.AspNetCore.DataProtection.Redis.csproj b/src/Microsoft.AspNetCore.DataProtection.Redis/Microsoft.AspNetCore.DataProtection.Redis.csproj
index e305facf8d..65b0d5c216 100644
--- a/src/Microsoft.AspNetCore.DataProtection.Redis/Microsoft.AspNetCore.DataProtection.Redis.csproj
+++ b/src/Microsoft.AspNetCore.DataProtection.Redis/Microsoft.AspNetCore.DataProtection.Redis.csproj
@@ -3,8 +3,8 @@
- Redis storrage support as key store.
- 0.1.0
+ Redis storage support as key store.
+ 0.3.0
net46;netstandard1.5
$(NoWarn);CS1591
true
diff --git a/src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs b/src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs
index 4cde160961..5a64d5e44f 100644
--- a/src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs
+++ b/src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs
@@ -30,7 +30,7 @@ namespace Microsoft.Extensions.DependencyInjection
throw new ArgumentNullException(nameof(services));
}
- services.AddSingleton();
+ services.TryAddSingleton();
services.AddOptions();
AddDataProtectionServices(services);
diff --git a/src/Microsoft.AspNetCore.DataProtection/RC1ForwardingActivator.cs b/src/Microsoft.AspNetCore.DataProtection/RC1ForwardingActivator.cs
deleted file mode 100644
index 9d76aaac49..0000000000
--- a/src/Microsoft.AspNetCore.DataProtection/RC1ForwardingActivator.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using Microsoft.Extensions.Logging;
-
-namespace Microsoft.AspNetCore.DataProtection
-{
- internal class RC1ForwardingActivator: SimpleActivator
- {
- private const string From = "Microsoft.AspNet.DataProtection";
- private const string To = "Microsoft.AspNetCore.DataProtection";
- private readonly ILogger _logger;
-
- public RC1ForwardingActivator(IServiceProvider services) : this(services, DataProtectionProviderFactory.GetDefaultLoggerFactory())
- {
- }
-
- public RC1ForwardingActivator(IServiceProvider services, ILoggerFactory loggerFactory) : base(services)
- {
- _logger = loggerFactory.CreateLogger(typeof(RC1ForwardingActivator));
- }
-
- public override object CreateInstance(Type expectedBaseType, string implementationTypeName)
- {
- if (implementationTypeName.Contains(From))
- {
- var forwardedImplementationTypeName = implementationTypeName.Replace(From, To);
- var type = Type.GetType(forwardedImplementationTypeName, false);
- if (type != null)
- {
- _logger.LogDebug("Forwarded activator type request from {FromType} to {ToType}",
- implementationTypeName,
- forwardedImplementationTypeName);
-
- implementationTypeName = forwardedImplementationTypeName;
- }
- }
- return base.CreateInstance(expectedBaseType, implementationTypeName);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.DataProtection/TypeForwardingActivator.cs b/src/Microsoft.AspNetCore.DataProtection/TypeForwardingActivator.cs
new file mode 100644
index 0000000000..3865adbf37
--- /dev/null
+++ b/src/Microsoft.AspNetCore.DataProtection/TypeForwardingActivator.cs
@@ -0,0 +1,73 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Text.RegularExpressions;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.AspNetCore.DataProtection
+{
+ internal class TypeForwardingActivator : SimpleActivator
+ {
+ private const string OldNamespace = "Microsoft.AspNet.DataProtection";
+ private const string CurrentNamespace = "Microsoft.AspNetCore.DataProtection";
+ private readonly ILogger _logger;
+ private static readonly Regex _versionPattern = new Regex(@",\s?Version=(\d+\.?)(\d+\.?)?(\d+\.?)?(\d+\.?)?", RegexOptions.Compiled, TimeSpan.FromSeconds(2));
+
+ public TypeForwardingActivator(IServiceProvider services)
+ : this(services, DataProtectionProviderFactory.GetDefaultLoggerFactory())
+ {
+ }
+
+ public TypeForwardingActivator(IServiceProvider services, ILoggerFactory loggerFactory)
+ : base(services)
+ {
+ _logger = loggerFactory.CreateLogger(typeof(TypeForwardingActivator));
+ }
+
+ public override object CreateInstance(Type expectedBaseType, string originalTypeName)
+ => CreateInstance(expectedBaseType, originalTypeName, out var _);
+
+ // for testing
+ internal object CreateInstance(Type expectedBaseType, string originalTypeName, out bool forwarded)
+ {
+ var forwardedTypeName = originalTypeName;
+ var candidate = false;
+ if (originalTypeName.Contains(OldNamespace))
+ {
+ candidate = true;
+ forwardedTypeName = originalTypeName.Replace(OldNamespace, CurrentNamespace);
+ }
+
+#if NET46
+ if (candidate || forwardedTypeName.Contains(CurrentNamespace))
+ {
+ candidate = true;
+ forwardedTypeName = RemoveVersionFromAssemblyName(forwardedTypeName);
+ }
+#elif NETSTANDARD1_3
+#else
+#error Target framework needs to be updated
+#endif
+
+ if (candidate)
+ {
+ var type = Type.GetType(forwardedTypeName, false);
+ if (type != null)
+ {
+ _logger.LogDebug("Forwarded activator type request from {FromType} to {ToType}",
+ originalTypeName,
+ forwardedTypeName);
+ forwarded = true;
+ return base.CreateInstance(expectedBaseType, forwardedTypeName);
+ }
+ }
+
+ forwarded = false;
+ return base.CreateInstance(expectedBaseType, originalTypeName);
+ }
+
+ protected string RemoveVersionFromAssemblyName(string forwardedTypeName)
+ => _versionPattern.Replace(forwardedTypeName, "");
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.DataProtection.Test/RC1ForwardingActivatorTests.cs b/test/Microsoft.AspNetCore.DataProtection.Test/RC1ForwardingActivatorTests.cs
deleted file mode 100644
index d0f01533b7..0000000000
--- a/test/Microsoft.AspNetCore.DataProtection.Test/RC1ForwardingActivatorTests.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using Microsoft.Extensions.DependencyInjection;
-using Xunit;
-
-namespace Microsoft.AspNetCore.DataProtection
-{
- public class RC1ForwardingActivatorTests
- {
- [Fact]
- public void CreateInstance_ForwardsToNewNamespaceIfExists()
- {
- // Arrange
- var serviceCollection = new ServiceCollection();
- serviceCollection.AddDataProtection();
- var services = serviceCollection.BuildServiceProvider();
- var activator = services.GetActivator();
-
- // Act
- var name = "Microsoft.AspNet.DataProtection.RC1ForwardingActivatorTests+ClassWithParameterlessCtor, Microsoft.AspNet.DataProtection.Test";
- var instance = activator.CreateInstance