Hi, we have encountered strange exception after one of ours project's target framework has been upgraded from netcoreapp3.1 to net5.0.
This is the exception message:
Unhandled exception. System.Security.VerificationException: Method ConsoleApp1.ComponentRegistry`1[ConsoleApp1.NamedObjectComponent`1[TNamedObject]].Register: type argument 'TComponentA' violates the constraint of type parameter 'TComponent'.
at ConsoleApp1.SingleTypeNamedObjectContainer`1.Register[TComponentA]()
at ConsoleApp1.NamedObjectContainer.Register[TNamedObject,TComponent]() in /Users/gureev/RiderProjects/ConsoleApp1/ConsoleApp1/Program.cs:line 87
at ConsoleApp1.Program.Main(String[] args) in /Users/gureev/RiderProjects/ConsoleApp1/ConsoleApp1/Program.cs:line 108
I made simple console app to reproduce it:
class Program
{
public abstract class NamedObject { }
public class FooNamedObject : NamedObject { }
public abstract class NamedObjectComponent { }
public abstract class NamedObjectComponent<TNamedObject> : NamedObjectComponent where TNamedObject : NamedObject { }
public class FooNamedObjectComponent : NamedObjectComponent<FooNamedObject> { }
public abstract class SingleTypeNamedObjectContainer
{
internal SingleTypeNamedObjectContainer() { }
internal abstract Type NamedObjectType { get; }
}
public class SingleTypeNamedObjectContainer<TNamedObject> : SingleTypeNamedObjectContainer
where TNamedObject : NamedObject
{
private readonly ComponentRegistry<NamedObjectComponent<TNamedObject>> components =
new ComponentRegistry<NamedObjectComponent<TNamedObject>>();
internal override Type NamedObjectType => typeof(TNamedObject);
public void Register<TComponentA>()
where TComponentA : NamedObjectComponent<TNamedObject>, new()
{
components.Register<TComponentA>();
}
}
public class ComponentRegistry<TBaseComponent> where TBaseComponent : class
{
private readonly HashSet<Type> componentTypes = new HashSet<Type>();
private readonly Dictionary<Type, Func<TBaseComponent>> componentFactories =
new Dictionary<Type, Func<TBaseComponent>>();
public void Register<TComponent>()
where TComponent : class, TBaseComponent, new()
{
Register(() => new TComponent());
}
public void Register<TComponent>(Func<TComponent> componentFactory)
where TComponent : class, TBaseComponent
{
componentTypes.Add(typeof(TComponent));
componentFactories.Add(typeof(TComponent), componentFactory);
}
}
public class NamedObjectContainer
{
private readonly Dictionary<Type, SingleTypeNamedObjectContainer> subcontainersByNamedObjectType =
new Dictionary<Type, SingleTypeNamedObjectContainer>();
private readonly Dictionary<Type, SingleTypeNamedObjectContainer> subcontainersByRegisteredType =
new Dictionary<Type, SingleTypeNamedObjectContainer>();
public SingleTypeNamedObjectContainer<TNamedObject> RegisterNamedObjectType<TNamedObject>()
where TNamedObject : NamedObject
{
return RegisterSubcontainer(new SingleTypeNamedObjectContainer<TNamedObject>());
}
public TSubcontainer RegisterSubcontainer<TSubcontainer>(TSubcontainer subcontainer)
where TSubcontainer : SingleTypeNamedObjectContainer
{
subcontainersByNamedObjectType.Add(subcontainer.NamedObjectType, subcontainer);
subcontainersByRegisteredType.Add(typeof(TSubcontainer), subcontainer);
return subcontainer;
}
internal void Register<TNamedObject, TComponent>()
where TNamedObject : NamedObject
where TComponent : NamedObjectComponent<TNamedObject>, new()
{
GetSubcontainerFor<TNamedObject>().Register<TComponent>();
}
public SingleTypeNamedObjectContainer<TNamedObject> GetSubcontainerFor<TNamedObject>()
where TNamedObject : NamedObject
{
return (SingleTypeNamedObjectContainer<TNamedObject>)GetSubcontainerFor(typeof(TNamedObject));
}
public SingleTypeNamedObjectContainer GetSubcontainerFor(Type baseNamedObjectType)
{
return subcontainersByNamedObjectType[baseNamedObjectType];
}
}
static void Main(string[] args)
{
var contaner = new NamedObjectContainer();
contaner.RegisterNamedObjectType<FooNamedObject>();
contaner.Register<FooNamedObject, FooNamedObjectComponent>();
}
}
If you run this code with target netcoreapp3.1 - it works.
But if you run with target netcoreapp5.0 - exception throws.
Dotnet sdk 5.0.100
OS: MacOS Catalina (x64), Windows 10 1903 (x64)
Yes, works on 3.1.
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq
See info in area-owners.md if you want to be subscribed.
Issue Details
Hi, we have encountered strange exception after one of ours project's target framework has been upgraded from netcoreapp3.1 to net5.0.
This is the exception message:
Unhandled exception. System.Security.VerificationException: Method ConsoleApp1.ComponentRegistry`1[ConsoleApp1.NamedObjectComponent`1[TNamedObject]].Register: type argument 'TComponentA' violates the constraint of type parameter 'TComponent'.
at ConsoleApp1.SingleTypeNamedObjectContainer`1.Register[TComponentA]()
at ConsoleApp1.NamedObjectContainer.Register[TNamedObject,TComponent]() in /Users/gureev/RiderProjects/ConsoleApp1/ConsoleApp1/Program.cs:line 87
at ConsoleApp1.Program.Main(String[] args) in /Users/gureev/RiderProjects/ConsoleApp1/ConsoleApp1/Program.cs:line 108
I made simple console app to reproduce it:
class Program
{
public abstract class NamedObject { }
public class FooNamedObject : NamedObject { }
public abstract class NamedObjectComponent { }
public abstract class NamedObjectComponent<TNamedObject> : NamedObjectComponent where TNamedObject : NamedObject { }
public class FooNamedObjectComponent : NamedObjectComponent<FooNamedObject> { }
public abstract class SingleTypeNamedObjectContainer
{
internal SingleTypeNamedObjectContainer() { }
internal abstract Type NamedObjectType { get; }
}
public class SingleTypeNamedObjectContainer<TNamedObject> : SingleTypeNamedObjectContainer
where TNamedObject : NamedObject
{
private readonly ComponentRegistry<NamedObjectComponent<TNamedObject>> components =
new ComponentRegistry<NamedObjectComponent<TNamedObject>>();
internal override Type NamedObjectType => typeof(TNamedObject);
public void Register<TComponentA>()
where TComponentA : NamedObjectComponent<TNamedObject>, new()
{
components.Register<TComponentA>();
}
}
public class ComponentRegistry<TBaseComponent> where TBaseComponent : class
{
private readonly HashSet<Type> componentTypes = new HashSet<Type>();
private readonly Dictionary<Type, Func<TBaseComponent>> componentFactories =
new Dictionary<Type, Func<TBaseComponent>>();
public void Register<TComponent>()
where TComponent : class, TBaseComponent, new()
{
Register(() => new TComponent());
}
public void Register<TComponent>(Func<TComponent> componentFactory)
where TComponent : class, TBaseComponent
{
componentTypes.Add(typeof(TComponent));
componentFactories.Add(typeof(TComponent), componentFactory);
}
}
public class NamedObjectContainer
{
private readonly Dictionary<Type, SingleTypeNamedObjectContainer> subcontainersByNamedObjectType =
new Dictionary<Type, SingleTypeNamedObjectContainer>();
private readonly Dictionary<Type, SingleTypeNamedObjectContainer> subcontainersByRegisteredType =
new Dictionary<Type, SingleTypeNamedObjectContainer>();
public SingleTypeNamedObjectContainer<TNamedObject> RegisterNamedObjectType<TNamedObject>()
where TNamedObject : NamedObject
{
return RegisterSubcontainer(new SingleTypeNamedObjectContainer<TNamedObject>());
}
public TSubcontainer RegisterSubcontainer<TSubcontainer>(TSubcontainer subcontainer)
where TSubcontainer : SingleTypeNamedObjectContainer
{
subcontainersByNamedObjectType.Add(subcontainer.NamedObjectType, subcontainer);
subcontainersByRegisteredType.Add(typeof(TSubcontainer), subcontainer);
return subcontainer;
}
internal void Register<TNamedObject, TComponent>()
where TNamedObject : NamedObject
where TComponent : NamedObjectComponent<TNamedObject>, new()
{
GetSubcontainerFor<TNamedObject>().Register<TComponent>();
}
public SingleTypeNamedObjectContainer<TNamedObject> GetSubcontainerFor<TNamedObject>()
where TNamedObject : NamedObject
{
return (SingleTypeNamedObjectContainer<TNamedObject>)GetSubcontainerFor(typeof(TNamedObject));
}
public SingleTypeNamedObjectContainer GetSubcontainerFor(Type baseNamedObjectType)
{
return subcontainersByNamedObjectType[baseNamedObjectType];
}
}
static void Main(string[] args)
{
var contaner = new NamedObjectContainer();
contaner.RegisterNamedObjectType<FooNamedObject>();
contaner.Register<FooNamedObject, FooNamedObjectComponent>();
}
}
If you run this code with target netcoreapp3.1 - it works.
But if you run with target netcoreapp5.0 - exception throws.
Dotnet sdk 5.0.100
OS: MacOS Catalina (x64), Windows 10 1903 (x64)
Yes, works on 3.1.
| Author: | GureevLeonid |
|---|---|
| Assignees: | - |
| Labels: | `area-System.Security`, `untriaged` |
| Milestone: | - |
Hmm, VerificationException, if I understand correctly, means that something or unverifiable at runtime. @janvorli might you know best how to proceed here?
Let me run the repro locally and see where the exception stems from in the native runtime.
Most helpful comment
Let me run the repro locally and see where the exception stems from in the native runtime.