I have a NuGet package that depends on SimpleInjector.
I am just letting you know that your restrictive use of the ObsoleteAttribute (that is, setting the error argument to true) is causing a problem with supporting your library. As you might already know, the default NuGet behavior will _silently_ upgrade a package to the lowest common version number. So, if another library decides to support only 3.x and that is installed into someone's target project along with mine (which supports 2.x +), NuGet will install 3.x into the project.
This dilemma for those who depend on SimpleInjector has left us with 3 options:
- Don't support SimpleInjector 3.x and set the NuGet maximum version < 3.x (which by the way is totally ignored when doing a Package-Update).
- Create a separate NuGet package for SimpleInjector 2.x and SimpleInjector 3.x.
- Use .NET reflection to work around the
ObsoleteAttribute restriction (yuck!)
I went with the 3rd option. But this means that patching the code to support either version has gone from this:
// Extension methods for cross-version support of Simple Injector 2.x and 3.x.
// This will succeed on 2.x and will be bypassed on 3.x
public static void RegisterCollection(this Container container, Type serviceType,
IEnumerable<Type> serviceTypes)
{
container.RegisterAll(serviceType, serviceTypes);
}
// This will succeed on 2.x and will be bypassed on 3.x
public static void RegisterCollection<TService>(this Container container,
IEnumerable<TService> containerUncontrolledCollection) where TService : class
{
container.RegisterAll(containerUncontrolledCollection);
}
To this:
// Extension methods for cross-version support of Simple Injector 2.x and 3.x.
// This will succeed on 2.x and will be bypassed on 3.x
public static void RegisterCollection(this Container container, Type serviceType,
IEnumerable<Type> serviceTypes)
{
// container.RegisterAll(serviceType, serviceTypes);
var method = container.GetType().GetMethod(
"RegisterAll",
BindingFlags.Instance | BindingFlags.Public,
null,
new Type[] { typeof(Type), typeof(IEnumerable<Type>) },
null);
if (method != null)
{
method.Invoke(container, new object[] { serviceType, serviceTypes });
}
}
// This will succeed on 2.x and will be bypassed on 3.x
public static void RegisterCollection<TService>(this Container container,
IEnumerable<TService> containerUncontrolledCollection) where TService : class
{
// container.RegisterAll(containerUncontrolledCollection);
var method = container.GetType().GetMethods()
.Where(mi => mi.Name == "RegisterAll")
.Select(mi => new { M = mi, P = mi.GetParameters(), A = mi.GetGenericArguments() })
.Where(x => x.A.Length == 1
&& x.P.Length == 1
&& x.P[0].Name == "collection")
.Select(x => x.M)
.FirstOrDefault();
if (method != null)
{
var genericMethod = method.MakeGenericMethod(new Type[] { typeof(TService) });
genericMethod.Invoke(container, new object[] { containerUncontrolledCollection });
}
}
If you would have just marked the methods obsolete without raising a compile error I wouldn't have to resort to such measures, because I don't have any control over whether the end user will have 2.x or 3.x in their project - that is up to NuGet.
Adding an extension method to mimic the 3.x behavior when 2.x is installed would have been great. Since an instance method takes precedence over an extension method, the fact that 3.x has them would normally make the first code silently ignored. Except when I upgraded to 3.x, the backward-compatibility code failed because the ObsoleteAttribute caused it not to build.
I have a NuGet package that depends on SimpleInjector.
I am just letting you know that your restrictive use of the
ObsoleteAttribute(that is, setting the error argument to true) is causing a problem with supporting your library. As you might already know, the default NuGet behavior will _silently_ upgrade a package to the lowest common version number. So, if another library decides to support only 3.x and that is installed into someone's target project along with mine (which supports 2.x +), NuGet will install 3.x into the project.This dilemma for those who depend on SimpleInjector has left us with 3 options:
ObsoleteAttributerestriction (yuck!)I went with the 3rd option. But this means that patching the code to support either version has gone from this:
To this:
If you would have just marked the methods obsolete without raising a compile error I wouldn't have to resort to such measures, because I don't have any control over whether the end user will have 2.x or 3.x in their project - that is up to NuGet.
Adding an extension method to mimic the 3.x behavior when 2.x is installed would have been great. Since an instance method takes precedence over an extension method, the fact that 3.x has them would normally make the first code silently ignored. Except when I upgraded to 3.x, the backward-compatibility code failed because the
ObsoleteAttributecaused it not to build.