Open shvez opened 4 years ago
About sample. Everything happens inside Application.Run method. During the first start, it should fail in Application.cs:29 because System.Configuration.ConfigurationManager is not shared with 'Default' context. that can be fixed by uncommenting line AssemblyLoadContext.cs:36
Next step is to get non-default values in line Application.cs:21 and Application.cs:24
@vitek-karas here is the report about ConfigurationManager issues
The best way to avoid duplicate copies of assemblies for the plugin is to modify the project/package references. So in the Application.csproj
you can change the references to look like this:
<ItemGroup>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.6.0">
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AppInterfaces\AppInterfaces.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
</ItemGroup>
Then you don't need any special cases in the resolver as the files will not get copied over to the output.
That doesn't answer why the configuration is not loaded though.
That said the usage of statics like ConfigurationManager.GetSection
will not work as statics are shared then (only one copy for the entire app). To get multiple copies you would need to get mutliple copies of the System.Configuration.ConfigurationManager
- which is in theory possible, but definitely not recommended.
Just curious: What is the scenario you're trying to solve? If these are logically separate applications, why not run them as separate processes? That is the best level of isolation. Neither AppDomain nor AssemblyLoadContext really provide true isolation (other than some of the assembly resolution isolation).
Thanks a lot for the update.
What is the scenario you're trying to solve? So far we had a socket server native host application that loads managed applications as plugins. We had only one process that is able to load many applications and share ports between them. now when we have a netcoreapp3 host application we still have to keep the option of port sharing.
all these hassles about isolation are just because we have statics in our code.
Another thing that complicates is that we have public sdk that is used by customers a lot for writing their own applications. Some of them extend our stuff, some write their own apps from scratch. So basically I do not have any clue what are they doing but we try to be as backward compatible as possible to reduce upgrade complexities.
we managed to get configuration stuff working but a solution requires some extra work from us and from developers.
we do it next way:
System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None)
callApplicationSettingsBase
children we get section like this
var t = typeof(T);//T is derived from ApplicationSettingsBase
var sectionName = "applicationSettings/" + t.Namespace + "." + t.Name;
var clientSection = config.GetSection(sectionName) as ClientSettingsSection;
For classes derived from ConfigurationSection
like WebRpcSettings
in the sample we open config file using XMLDocument get XmlReader for corresponding section and then inside a constructor of we call DeserializeSection(xmlReader)
.
I assume and hope that we do something wrong and there are better and easier way :)
Thanks a lot for the description - I was mostly wondering "Why do you think you need to provide isolation?". Statics are a reason, but they imply that you expect your assemblies to be used in "weird" ways (as in loaded potentially twice and so on), ALCs will typically not help with that as by the time the code gets to you, it might already be too late.
EDT: Assembly 'Application' from the sample in our code is very basic assembly that is used to build real applications. So, it can be loaded twice or trice
ALCs will typically not help with that as, by the time the code gets to you, it might already be too late.
this part I did not really get.
I was mostly wondering
I hope there are more guys working with you and someone who is guru of ConfigurationManager could help :)
@jeffschwMSFT do we have any docs on how to port code from .NET Framework to .NET Core when using app domains to load assemblies? I suppose in .NET Core this would be using ALCs which would already take the deps.json file into consideration
We don't have a direct guide for migration, but there are pretty good docs on AssemblyLoadContext
and related classes and how to use them in various scenarios:
https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/overview
https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext
Hi, there. Let me start with a short description. We have a native application that loads .netframework runtime and assemblies. Every assembly represents some application and every application is loaded to its own app domain even if it is from the same assembly. We have used app.config file with corresponding settings classes. That was working fine.
Now we have a net core application that should do a similar thing. It should load the assemblies from above recompiled with minimum changes as net core assemblies. That minimum of changes required because we still need to run our native application with .netframework assemblies while we transit to the new net core application.
There are several questions:
I've prepared a small sample that does what we do Loader.zip
I'm using netcoreapp3.0