Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Add back most CreateInstance APIs to AppDomain and Activator#30809

Merged
jkotas merged 41 commits intodotnet:masterfrom
MarcoRossignoli:createinstanceapis
Jul 24, 2018
Merged

Add back most CreateInstance APIs to AppDomain and Activator#30809
jkotas merged 41 commits intodotnet:masterfrom
MarcoRossignoli:createinstanceapis

Conversation

@MarcoRossignoli
Copy link
Member

@MarcoRossignoli MarcoRossignoli commented Jul 3, 2018

}

[Fact]
static void CreateInstanceAssemblyResolve()
Copy link
Member Author

@MarcoRossignoli MarcoRossignoli Jul 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see anything obvious. It is possible that the assemblyFromResolveEvent path is unreachable code in CoreCLR if this does not hit it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try and let you know! Thank's for tip!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

@MarcoRossignoli MarcoRossignoli Jul 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i cannot trigger return null branch

Agree. This branch looks like unreachable code. I think it should be fine to delete it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkotas is this useful today?I read around was used for call/callvirt IL.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, it is fine to delete these checks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@MarcoRossignoli
Copy link
Member Author

D:\j\workspace\windows-TGrou---74aa877a\Tools\partialfacades.task.targets(64,5): warning : Did not find type 'T:System.Runtime.Remoting.ObjectHandle' in any of the seed assemblies. [D:\j\workspace\windows-TGrou---74aa877a\src\System.Runtime\src\System.Runtime.csproj]

@danmosemsft @jkotas mmm...first time i get this error...with my local clr build/tests works well...what i'm missing?

@ericstj
Copy link
Member

ericstj commented Jul 3, 2018

You need to make sure corefx has picked up the coreclr build where you added this type. Probably #30808

@MarcoRossignoli
Copy link
Member Author

MarcoRossignoli commented Jul 3, 2018

You need to make sure corefx has picked up the coreclr build where you added this type. Probably #30808

Sorry i don't understand...here is CI that fail...PR you linked could be already current clr bit used by CI self, isn't it?
Ahh..is open not merged...clear! Thank's a lot @ericstj!

@ericstj
Copy link
Member

ericstj commented Jul 3, 2018

Looks like @stephentoub just merged that, so we can now rerun CI.
@dotnet-bot test this please


if (assemblyName == null)
throw new ArgumentNullException("assemblyName");
Contract.EndContractBlock();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can delete these EndContractBlock annotations too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

throw new NullReferenceException();

if (assemblyName == null)
throw new ArgumentNullException("assemblyName");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We use nameof(assemblyName) for these

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -0,0 +1,22 @@
using System;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

License header

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\System.Private.Uri\src\System.Private.Uri.csproj" />
<ProjectReference Include="..\..\System.Diagnostics.Contracts\src\System.Diagnostics.Contracts.csproj" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be needed once you cleanup the unnecessary annotations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
return Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), "TestLoadAssembly.dll"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: These can be return oh?.Unwrap()

{
ObjectHandle oh = null;

if(exceptionType != null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Space if (

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

// 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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit double blank line

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

public ObjectHandle CreateInstance(string assemblyName, string typeName)
{
if (assemblyName == null)
throw new ArgumentNullException(nameof(assemblyName));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please add the braces here to have uniformity with the other exceptions being thrown in this file

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

public object CreateInstanceAndUnwrap(string assemblyName, string typeName)
{
ObjectHandle oh = CreateInstance(assemblyName, typeName);

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extra line

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i added extraline in all methods...remove all?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it is neither accompanied by any type of brace nor its more than a couple of lines

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can factor out these two lines into private function something like CheckValidity. will make the repetition less

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


public static IEnumerable<object[]> TestingCreateInstanceObjectHandleFullSignatureData()
{
//string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, returnedFullNameType
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add some space after //

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


public static TheoryData<string, string, string, string, Type> TestingCreateInstanceFromObjectHandleData => new TheoryData<string, string, string, string, Type>()
{
//string physicalFileName, string assemblyFile, string typeName, returnedFullNameType, expectedException
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after //

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


public static TheoryData<string, string, string, Type, bool> TestingCreateInstanceObjectHandleData => new TheoryData<string, string, string, Type, bool>()
{
//string assemblyName, string typeName, returnedFullNameType, expectedException
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after //

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add space after all comments

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for all this commit I'm a little bit fried today 😵

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np :)

@MarcoRossignoli
Copy link
Member Author

@dotnet-bot test this please

@danmoseley
Copy link
Member

@Anipik @jkotas any further feedback?

@danmoseley
Copy link
Member

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.

@danmoseley danmoseley added the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label Jul 24, 2018
@jkotas jkotas removed the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label Jul 24, 2018
@jkotas jkotas merged commit ab6f3da into dotnet:master Jul 24, 2018
@MarcoRossignoli MarcoRossignoli deleted the createinstanceapis branch July 24, 2018 06:00
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add back most CreateInstance APIs to AppDomain and Activator

6 participants