Changes to external references are no longer updated correctly

SyntaxEditor .NET Languages Add-on for Windows Forms Forum

Posted 4 years ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Version: 14.1.0312
Platform: Universal Windows Controls
Environment: Windows 7 (64-bit)
Avatar

Hi,

we are generating some .net assemblies during runtime. The generated classes and namespaces can change during runtime. With v288 the external references were updated correctly, but since we updated to v312 this does not work anymore.

Internally we remove the old version from all DotNetProjectResolver instances, then add the same assembly again and reparse all documents. This used to work with v288 and the intelli and everything was updated correctly. Now the intelli still contains the old information of the assembly while the generated assembly is correct.

I assume the error was introduced with the following feature since this is the only relvant entry from the changelog:

Updated the AssemblyCodeRepository to not increment assembly reference counts if an assembly being added to a project resolver is already loaded in that project resolver.

When I restart my app the intelli info is correct. I have debuged my code and have verified that the reference counter is 0 before the assembly is added again. So I guess this must be an internal problem of the AssemblyCodeRepository.

[Modified 4 years ago]


Best regards, Tobias Lingemann.

Comments (5)

Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Tobias,

Can you double check which version you are using right now?  Build 312 was v13.1 (not v14.1).  Or did you mean you are v14.1.0322?

By the way, did you know that AssemblyCodeRepository has a Refresh method on it?  Have you tried using that for your scenario, since it sounds like that's geared more for what you are doing?


Actipro Software Support

Posted 4 years ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

Hi,

Can you double check which version you are using right now? Build 312 was v13.1 (not v14.1). Or did you mean you are v14.1.0322?

Our license for the .net Add-on has expired. This is why we are stuck with v312 at the moment (with source code). For the rest of the components we are currently using v320.

By the way, did you know that AssemblyCodeRepository has a Refresh method on it? Have you tried using that for your scenario, since it sounds like that's geared more for what you are doing?

That doesn't really work for me since it requires the instance of an assembly. Maybe it will work if I rewrite the method to use a different AppDomain that then loads the assembly. Since you cannot really unload an assembly in .net we are loading these kind of assemblies within special AppDomain instances that can be unloaded if they are no longer needed.

I will try modifying the Refresh method, but I am not quite sure if it will help.

[Modified 4 years ago]


Best regards, Tobias Lingemann.

Posted 4 years ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

Okay, my idea didn't really work, but I think I found the problem. Since we load the assemblies in reflection-only mode, the assembly location is not obtained. Therefore there is no check if the cache must be updated and the cached info is always used.

Right now my workaround would be to prune the cache after the assemblies were updated, then remove the references (must be after pruning) and add them again. This isn't really the ideal because I can't call the prune method for only a specific assembly.

So my new guess is that the problem came in with v290:

Added the AssemblyCodeRepository.UseReflectionOnlyLoad property which can be set to false to use non-reflection-only Assembly loads.

[Modified 4 years ago]


Best regards, Tobias Lingemann.

Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Tobias,

I compared the two builds 287 vs. 312.  While there is a minor update in DotNetProjectResolver.AddExternalReference, as long as you removed the reference from the DotNetProjectResolver first, that shouldn't matter.

Other than that, there are two main changes in AssemblyCodeRepository.  The first is updating the AppDomain.AssemblyResolve handler logic.  I'm not sure that would make a difference in your scenario though.

The second is that we used to do full Assembly loads if you were in .NET 1.1 or earlier and reflection-only Assembly loads if you were in .NET 2.0 or later.  In the newer code we no longer support .NET 1.1, so we do reflection-only Assembly loads by default.  You can turn off this behavior by setting AssemblyCodeRepository.UseReflectionOnlyLoad to false.  Perhaps changing that property will help your scenario.


Actipro Software Support

Answer - Posted 4 years ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

Hi,

so we do reflection-only Assembly loads by default. You can turn off this behavior by setting AssemblyCodeRepository.UseReflectionOnlyLoad to false. Perhaps changing that property will help your scenario.

As I said this causes the problem. At first I didn't realize this property was new. Setting UseReflectionOnlyLoad to false solves the problem since only this way the assembly location is obtained. With the default settings the assembly location is not obtained and thus the cache is not updated correctly.

For reference: http://msdn.microsoft.com/en-us/library/system.reflection.assembly.location%28v=vs.110%29.aspx

If the assembly is loaded from a byte array, such as when using the Load(Byte[]) method overload, the value returned is an empty string ("").

I would prefer using reflection only mode, because it reduces overhead and problems when loading assemblies. You should use ReflectionOnlyLoadFrom() instead.

[Modified 4 years ago]


Best regards, Tobias Lingemann.

The latest build of this product (v2018.1 build 0341) was released 3 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.