November Happy Hour will be moved to Thursday December 5th.
November Happy Hour will be moved to Thursday December 5th.
Update:
I have sucessfully updated the project to use EPiServer 11.1.0, and the initialization module ran without any problems.
I then tried to update EPiServer.ServiceLocation.Structuremap, which introduced some structuremap changes, form signed to unsigned.
I followed this article during the upgrade process:
Which means I did the following steps:
This lead to the initialization module breaking once agan, with the same errors.
As you wrote and known, upgrading Find from 9-11 causes upgrading CMS also. And there are a lot of breaking changes inside that.
I suggest you should create a support ticket and send your project to our support and they will help you.
/Son Do
Mads Gosvig, can you please share how you were able to get past the System.Collections.Immutable and System.Runtime.Loader issues? I am too upgrading a site similar to yours with Epi Find NestedConventions using ForInstancesOf.
I implemented the binding redirects, but I am still stuck on getting past the "Could not load type 'System.Runtime.Loader.AssemblyLoadContext' from assembly 'System.Runtime.Loader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a." runtime error.
I also removed old StructureMap packages and updated to 4.5.2 and Web 4.0.xxx and still no luck.
Thanks in advance for your assistance.
Hi Tom,
Actually I never resolved the issue.
I have reported it to EPiServer Support, and they are currently looking into the problem.
I will post an update as soon as I hear from them.
To anyone interested in this:
I have debugged this myself, and are in contact with Episerver support to see if I am correct in my assumptions:
The root cause of this problem is these 2 packages:
When installed I get the error. When I uninstall them the code does not throw an error, but of course the Razor views cannot be compiled do to C# 6.0 features.
So I tried to install these versions:
Which we had before the upgrade from 9.6 to 11.X - And this actually removes the error!
So I tried to install these versions:
And once again I get the error.
I have looked into the "ForInstanceOf<>" code from Episerver:
public static UnifiedSearchTypeRulesBuilder<T> ForInstanceOf<T>(this IUnifiedSearchRegistry registry)
{
Type type = typeof(T);
// This is okay.
var assemblies = ((IEnumerable<Assembly>) AppDomain.CurrentDomain.GetAssemblies());
// this is okay.
var assembliesWhere = assemblies.Where<Assembly>((Func<Assembly, bool>) (x => !x.IsDynamicAssembly()));
var assembliesWhereAsList = assembliesWhere.ToList();
var listOfTestAssemblies = new List<Type[]>();
foreach (var testAssembly in assembliesWhereAsList)
{
// Somewhere in here a System.Runtime.Loader missing dll is thrown.
var localTestAssemblies = testAssembly.GetTypes();
listOfTestAssemblies.Add(localTestAssemblies);
}
return new UnifiedSearchTypeRulesBuilder<T>(listOfTestAssemblies);
}
NOTICE: I have written this code by looking into Episerver code.
The error is thrown when the <assembly>.GetTypes() function is called on this specific assembly:
This assembly as far as I understand, have started to use System.Runtime.Loader in on of its assemblies.
If you look at the documentation for <assembly>.GetTypes():
https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.gettypes?view=netframework-4.7.2
Under exceptions the following is writen:
ReflectionTypeLoadException:
The assembly contains one or more types that cannot be loaded. The array returned by the Types property of this exception contains a Type object for each type that was loaded and null for each type that could not be loaded, while the LoaderExceptions property contains an exception for each type that could not be loaded.
So it seems to me like this behavior is expected from <assembly>.GetTypes().
And the fix could be to throw a try/catch block around your call to <assembly>.GetTypes().
Otherwise the LoaderException will be thrown (which I don't think is the correct behavior)
Maybe this will be helpful for others.
I will update this post once I hear back from support.
Another update:
I resolved my issues on my local development environment by doing as described in my last post.
But after a deploy to the test environment some new LoaderExceptions appeared.
So I have decided to copy the code from the ForInstanceOf<>() and implement it myself, with the try/catch blocks described earlier.
public static class CustomUnifiedSearchRegistryExtension
{
public static UnifiedSearchTypeRulesBuilder<T> ForInstanceOfWithErrorHandling<T>(this IUnifiedSearchRegistry registry)
{
var logger = ServiceLocator.Current.GetInstance<ILogger>();
Type type = typeof(T);
var assemblies = (IEnumerable<Assembly>) AppDomain.CurrentDomain.GetAssemblies();
var assembliesWhere = assemblies.Where(x => !EPiServer.Find.UnifiedSearch.AssemblyExtension.IsDynamicAssembly(x)).ToList();
var listOfGetTypes = new List<Type>();
foreach (var assembly in assembliesWhere)
{
try
{
var getMany = assembly.GetTypes() as IEnumerable<Type>;
listOfGetTypes.AddRange(getMany);
}
catch(ReflectionTypeLoadException reflectionTypeLoadException)
{
// Some assemblies could not be loaded - These are null in Types property.
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.gettypes?view=netframework-4.7.2
logger.Error($"Error: GetTypes() failed to load some Types in Assembly: {assembly.FullName}. Continuing with the ones it could load.", reflectionTypeLoadException);
var typesWhichCouldBeLoaded = reflectionTypeLoadException.Types.Where(x => x != null);
listOfGetTypes.AddRange(typesWhichCouldBeLoaded);
}
catch (Exception e)
{
logger.Error($"Error: GetTypes() failed on the following Assembly: {assembly.FullName}", e);
}
}
var assembliesSelectManyWhere = listOfGetTypes.Where(x =>
{
if (type.IsAssignableFrom(x))
{
return !registry.Contains(x);
}
return false;
});
foreach (var assemblyType in assembliesSelectManyWhere)
{
registry.Add(assemblyType);
}
return new UnifiedSearchTypeRulesBuilder<T>(registry);
}
}
This catches the ReflectionTypeLoaderExceptions and in the property Types should be a list of types that could be loaded, and null entries for Types that could not be loaded. (accordion to the documentation of GetTypes).
This "fixes" my problem, but there are of course still LoaderExceptions but they are handled gracefully.
I have asked Episerver support if this is an acceptable solution.
On a side note:
I looked into what was returned/added to registry.
It turns out that it finds 200 assemblies, and almost 70.000 types, only to find 1 type which is AssignableFrom and that is the Type that the extension was called upon.
So ...ForInstanceOf<TestPage>() only returns Type TestPage.
Episerver support have responded, and they agree with my solution to the problem.
So for now the fix for me is to override the ForInstanceOf<>().
Hi,
I am in the process of upgrading an EPiServer site, with EPiServer Find from 9.6.1 to 11, and I have stumbled upon a problem I haven't been able to figure out.
When running the following code in an initialization module, we get some LoaderException errors.
Turning on the Fusion log tells me the following:
I am able to install System.Collections.Immutable 1.1.37 (not 1.2.0 which it asked for in anoter fusion log) and create a binding redicret telling it to use 1.1.37 if asking for a 1.2.0
The problem is that I still get a LoaderException error:
And this assembly I can't resolve.
As far as I understand, this Nuget package is only for .NET Core projects, and therefore cannot be intsalled into a .NET framework 4.6.1 / 4.7.2 project.
I have been able to add the Nuget package, but it never gets into the project references. And it does not produce a .dll file which I can use.
The versions I am upgrading from and to:
We also have the following EPiServer packages installed:
Does anyone have any ideas how to solve / debug this problem any further?