dotnet / orleans

Cloud Native application framework for .NET
https://docs.microsoft.com/dotnet/orleans
MIT License
10.14k stars 2.04k forks source link

Silo Host Could not load file or assembly for 3rd party libraries used in Grain implementation project #4144

Closed narinfinity closed 6 years ago

narinfinity commented 6 years ago

Silo Host Could not load file or assembly for 3rd party libraries used in Grain implementation project. For ex. I'm using NuGet package -> Microsoft.Store.PartnerCenter, Version=1.7.0.0 in Grain implementation project (targets .net framework 4.7.1) and the SiloHost project (targets .netstandard2.0) has -> Microsoft.Store.PartnerCenter.dll in bin folder(SiloHostProject\bin\Debug\netcoreapp2.0), but it throws an exception -> Could not load file or assembly.

sergeybykov commented 6 years ago

Is Microsoft.Store.PartnerCenter getting copied to SiloHostProject\bin\Debug\netcoreapp2.0?

narinfinity commented 6 years ago

yes, it is getting copied into directory -> SiloHostProject\bin\Debug\netcoreapp2.0 as in SiloHostProject there is a registration -> .ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(MyGrainImpl).Assembly) .WithReferences()); it seems console-app (SiloHost) targeting -> .netstandard2.0 can not load (but gets copied in SiloHost's bin\Debug\netcoreapp2.0 directory) assemblies for 3rd party libs used (added as NuGet package) in Grain implementation project (where "MyGrainImpl:Grain, IMyGrainService" class is declared). On the other hand SiloHost(.netstandard2.0) will load these 3rd party assemblies if they also added into SiloHost project (which is not the desired solution). On the other hand, if SiloHost targets .net framework 4.7.1 (not .netstandard2.0) it loads assemblies normally.

ReubenBond commented 6 years ago

Does the SiloHost reference Microsoft.Store.PartnerCenter or is it just copied to the output? Could you post the stack trace?

narinfinity commented 6 years ago

if I add NuGet for -> "Microsoft.Store.PartnerCenter" into SiloHost(.netstandard2.0) it will only then load it, otherwise it can not (but "Microsoft.Store.PartnerCenter.dll" is copied into directory -> SiloHost\bin\Debug\netcoreapp2.0)

ReubenBond commented 6 years ago

@narinfinity1 does your output contain a *.deps.json file? If so, could you upload it?

sergeybykov commented 6 years ago

If you could also share your silo initialization code, that would help.

narinfinity commented 6 years ago

this is the line where app-parts are registered in SiloHost -> .ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(MyGrainImpl).Assembly).WithReferences());

where -> public class MyGrainImpl : Grain, IMyGrainService {...} is the class declared in Grain implementation project (targets .net 4.7.1 and adds NuGet for Microsoft.Store.PartnerCenter) where -> public interface IMyGrainService : IGrainWithGuidKey {...} is the interface with async method-signature declarations

ReubenBond commented 6 years ago

@narinfinity1 could you include your .deps.json file & .runtimeconfig.json file as well as the full error message? You say the SiloHost is .NET Standard 2.0. Just to be sure, you mean .NET Core 2.0 - is that correct?

narinfinity commented 6 years ago

the files You've mentioned I'll provide later, but the project where the SiloHost is created is a console-app(.netcoreapp2.0) targetting .netstandars2.0 apis, which is mostly compatible with .netcore2.0(includes more apis than .netstandars2.0) and partially compatible with .net framework 4.7.1(includes much more apis than .netstandars2.0)

ReubenBond commented 6 years ago

@narinfinity1 how are you launching the silo host if it targets .NET Standard 2.0 and not an actual runtime?

narinfinity commented 6 years ago

I mean SiloHost is created in a console app (my mistake above by writing -> class-lib) targetting .netstandars2.0

ReubenBond commented 6 years ago

@narinfinity1 you cannot create a console app targeting .NET Standard 2.0

narinfinity commented 6 years ago

SiloHost is a .netcoreapp2.0 targeting .netstandard2.0

narinfinity commented 6 years ago

yes, I mean .NET Core 2.0 app for SiloHost

ReubenBond commented 6 years ago

No worries, @narinfinity1 :) I'll wait for the deps/runtimeconfig files. Could you show me the .csproj file, too?

narinfinity commented 6 years ago

here the .csproj file content -> SiloHost1.csproj.txt

*.deps.json file content -> SiloHost1.deps.json.txt

runtimeconfig.json file content -> SiloHost1.runtimeconfig.json.txt

silo host creation -> ` namespace SiloHost1 { public class Program { public static int Main(string[] args) { return RunMainAsync().Result; }

    private static async Task<int> RunMainAsync()
    {
        try
        {
            var host = await StartSilo();
            Console.WriteLine("Press Enter to terminate...");
            Console.ReadLine();

            await host.StopAsync();

            return 0;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            return 1;
        }
    }

    private static async Task<ISiloHost> StartSilo()
    {
        var connectionString = "...";

        var builder = new SiloHostBuilder()
            .Configure(options => options.ClusterId = "My Silo Host Project")
            .UseAzureStorageClustering(options => options.ConnectionString = connectionString)
            .ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
            .ConfigureSiloName("Node1")
            .AddAzureTableGrainStorage("AzureTable", opt => opt.ConnectionString = connectionString)
            .ConfigureApplicationParts(parts =>
            {                    
                parts.AddApplicationPart(typeof(MyGrainImpl).Assembly).WithReferences();
                parts.AddApplicationPart(typeof(MyOtherGrainImpl).Assembly).WithReferences();                   
            })
            .ConfigureLogging(logging => logging.AddConsole());

        var host = builder.Build();
        await host.StartAsync();
        return host;
    }
}

} `

ReubenBond commented 6 years ago

@narinfinity1 I don't see Microsoft.Store.PartnerCenter.dll in any of the files you uploaded.

How do you launch the application? I believe you need to launch dotnet with --additionalprobingpath PATH_TO_FOLDER_CONTAINING_YOUR_DLL.

Note that is not an Orleans issue, it's just how .NET Core 2.0 works.

I would suggest that you either reference your library using <PackageReference> or using <Reference>. What you are trying to do is not typical.

narinfinity commented 6 years ago

in .net 4.7.1 project NuGet packs are referenced like -> `

..\..\..\packages\Microsoft.Store.PartnerCenter.1.7.0\lib\Net45\Microsoft.Store.PartnerCenter.dll

`

narinfinity commented 6 years ago

but .net core project uses these packs in its csproj file like ->


    <PackageReference Include="Microsoft.Orleans.Persistence.AzureStorage" Version="2.0.0-rc1" />
    <PackageReference Include="Microsoft.Orleans.Server" Version="2.0.0-rc1" />
  </ItemGroup>

  <ItemGroup>    
    <ProjectReference Include="..\..\Grains\PartnerCenter.Abstraction\PartnerCenter.Abstraction.csproj" />
    <ProjectReference Include="..\..\Grains\PartnerCenter.Service\PartnerCenter.Service.csproj" />
  </ItemGroup>```
narinfinity commented 6 years ago

All right, this is the issue of .Net Core, when trying to load .net framework project's NuGet packs' assemblies, which is not related to Orleans, so many Thanks to Orleans Team!