Add back most CreateInstance APIs to AppDomain and Activator#30809
Add back most CreateInstance APIs to AppDomain and Activator#30809jkotas merged 41 commits intodotnet:masterfrom MarcoRossignoli:createinstanceapis
Conversation
…Domain.CreateInstanceFrom
| } | ||
|
|
||
| [Fact] | ||
| static void CreateInstanceAssemblyResolve() |
There was a problem hiding this comment.
@jkotas with this test i wanted to cover https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/src/System/Activator.cs#L132 but after coverage analysis seems it doesn't pass here, any thoughts?
There was a problem hiding this comment.
I do not see anything obvious. It is possible that the assemblyFromResolveEvent path is unreachable code in CoreCLR if this does not hit it.
There was a problem hiding this comment.
What do you think is bettere here?Do we need to go down coreclr bit to understand why path is unreachable?Or this tests is enough for the scope of CreateInstance?
There was a problem hiding this comment.
I think you need to use invalid assembly name, like ,,,, to trigger the assembly resolve code path. AssemblyResolve event gets called for invalid names and can fix them up to something valid. For example, consider following program:
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Console.WriteLine(Assembly.Load(",,,,"));
}
private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
Console.WriteLine("AssemblyResolve: " + args.Name);
return typeof(Program).Assembly;
}
}It will print:
AssemblyResolve: ,,,,
test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
There was a problem hiding this comment.
I'll try and let you know! Thank's for tip!
There was a problem hiding this comment.
@jkotas it works(as expected 😏)!Branch covered...the only uncovered branch is https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/src/System/Activator.cs#L140 AssemblyContentType.WindowsRuntime is there a way to test WinRT assembly?
There was a problem hiding this comment.
Type.GetType("Windows.Foundation.Collections.StringMap, Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime") returns WinRT type on .NET Core 2.1 today.
So I would expect that using Windows.Foundation.Collections.StringMap as type name and Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime as assembly name here should hit this path.
For PlatformDetection.IsNotWinRTSupported platforms, it should throw exception.
There was a problem hiding this comment.
Ok WinRT branch covered.
The last two branch i can't trigger are:
https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/src/System/Activator.cs#L154 i cannot return null from assemblyFromResolveEvent or assemblyString == null because throw exception.
https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/src/System/Activator.cs#L167 i cannot trigger return null branch...maybe with some bindingAttr config...but i did't find anything so far(throw exceptions).
There was a problem hiding this comment.
i cannot trigger return null branch
Agree. This branch looks like unreachable code. I think it should be fine to delete it.
There was a problem hiding this comment.
Ok all branch of main method covered!
| public ObjectHandle CreateInstance(string assemblyName, string typeName) | ||
| { | ||
| // jit does not check for that, so we should do it ... | ||
| if (this == null) |
There was a problem hiding this comment.
@jkotas is this useful today?I read around was used for call/callvirt IL.
There was a problem hiding this comment.
Right, it is fine to delete these checks.
@danmosemsft @jkotas mmm...first time i get this error...with my local clr build/tests works well...what i'm missing? |
|
You need to make sure corefx has picked up the coreclr build where you added this type. Probably #30808 |
|
Looks like @stephentoub just merged that, so we can now rerun CI. |
|
|
||
| if (assemblyName == null) | ||
| throw new ArgumentNullException("assemblyName"); | ||
| Contract.EndContractBlock(); |
There was a problem hiding this comment.
You can delete these EndContractBlock annotations too.
| throw new NullReferenceException(); | ||
|
|
||
| if (assemblyName == null) | ||
| throw new ArgumentNullException("assemblyName"); |
There was a problem hiding this comment.
Nit: We use nameof(assemblyName) for these
| @@ -0,0 +1,22 @@ | |||
| using System; | |||
| </ItemGroup> | ||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\System.Private.Uri\src\System.Private.Uri.csproj" /> | ||
| <ProjectReference Include="..\..\System.Diagnostics.Contracts\src\System.Diagnostics.Contracts.csproj" /> |
There was a problem hiding this comment.
This should not be needed once you cleanup the unnecessary annotations.
|
|
||
| private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) | ||
| { | ||
| return Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), "TestLoadAssembly.dll")); |
There was a problem hiding this comment.
If other tests in this assembly happen to trigger AssemblyResolve event for unrelated assembly, this is going to break them. This AssemblyResolve event needs to be coded such that it is guaranteed to not affect other tests in the process, or this test needs to be launched in its own process.
| { | ||
| ObjectHandle oh = CreateInstance(assemblyName, typeName); | ||
|
|
||
| return (oh != null) ? oh.Unwrap() : null; |
There was a problem hiding this comment.
Nit: These can be return oh?.Unwrap()
| { | ||
| ObjectHandle oh = null; | ||
|
|
||
| if(exceptionType != null) |
There was a problem hiding this comment.
i'm suspecting that some of you are bot, should be night in Redmond 😃
|
|
||
| public static IEnumerable<object[]> TestingCreateInstanceObjectHandleFullSignatureWinRT() | ||
| { | ||
| //string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, returnedFullNameType |
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
| public ObjectHandle CreateInstance(string assemblyName, string typeName) | ||
| { | ||
| if (assemblyName == null) | ||
| throw new ArgumentNullException(nameof(assemblyName)); |
There was a problem hiding this comment.
can you please add the braces here to have uniformity with the other exceptions being thrown in this file
| public object CreateInstanceAndUnwrap(string assemblyName, string typeName) | ||
| { | ||
| ObjectHandle oh = CreateInstance(assemblyName, typeName); | ||
|
|
There was a problem hiding this comment.
i added extraline in all methods...remove all?
There was a problem hiding this comment.
yes, it is neither accompanied by any type of brace nor its more than a couple of lines
There was a problem hiding this comment.
is there a fixed rule for empty line? for example https://github.com/MarcoRossignoli/corefx/blob/ae8636faa74119668cdc605fd77a0a7361a31335/src/System.Runtime.Extensions/src/System/AppDomain.cs#L288 there isn't extraline
There was a problem hiding this comment.
I dont remember if there is coding guideline for this. This is the general feedback i got earlier.
| Assert.Equal(returnedFullNameType, oh.Unwrap().GetType().FullName); | ||
|
|
||
| obj = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(assemblyName: assemblyName, typeName: type); | ||
| Assert.NotNull(obj); |
There was a problem hiding this comment.
can factor out these two lines into private function something like CheckValidity. will make the repetition less
|
|
||
| public static IEnumerable<object[]> TestingCreateInstanceObjectHandleFullSignatureData() | ||
| { | ||
| //string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, returnedFullNameType |
|
|
||
| public static TheoryData<string, string, string, string, Type> TestingCreateInstanceFromObjectHandleData => new TheoryData<string, string, string, string, Type>() | ||
| { | ||
| //string physicalFileName, string assemblyFile, string typeName, returnedFullNameType, expectedException |
|
|
||
| public static TheoryData<string, string, string, Type, bool> TestingCreateInstanceObjectHandleData => new TheoryData<string, string, string, Type, bool>() | ||
| { | ||
| //string assemblyName, string typeName, returnedFullNameType, expectedException |
There was a problem hiding this comment.
sorry for all this commit I'm a little bit fried today 😵
|
@dotnet-bot test this please |
|
Let's give @jkotas a few days in case he is looking at github. There are subtleties to these API's that predate me so I want to get this right before we commit it. |
closes https://github.com/dotnet/corefx/issues/30190
Code was taken from https://referencesource.microsoft.com/
/cc @jkotas @danmosemsft @ericstj