Skip to content

Commit

Permalink
Return only direct module references as dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
MarinAtanasov committed May 26, 2019
1 parent 03bd20c commit bd1e2f3
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 20 deletions.
29 changes: 15 additions & 14 deletions Core/AppBrix.Utils/CommonExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,23 @@ public static class CommonExtensions
{
#region Types and enums extensions
/// <summary>
/// Get all of the referenced assemblies recursively,
/// starting with the provided assembly.
/// Get the referenced assemblies, starting with the provided assembly.
/// </summary>
/// <param name="current">The current assembly.</param>
/// <returns>All referenced assemblies.</returns>
public static IEnumerable<Assembly> GetAllReferencedAssemblies(this Assembly current)
/// <param name="recursive">If true, gets all references. If false, gets only the direct ones.</param>
/// <returns>The referenced assemblies.</returns>
public static IEnumerable<Assembly> GetReferencedAssemblies(this Assembly current, bool recursive)
{
var names = new HashSet<string> { current.GetName().FullName };
var locations = new HashSet<string> { current.Location };
var assemblyQueue = new List<Assembly> { current };

for (int i = 0; i < assemblyQueue.Count; i++)
{
foreach (var reference in assemblyQueue[i].GetReferencedAssemblies())
var referencedAssemblies = assemblyQueue[i].GetReferencedAssemblies();
for (int j = 0; j < referencedAssemblies.Length; j++)
{
var reference = referencedAssemblies[j];
if (!names.Add(reference.FullName))
continue;

Expand All @@ -40,22 +42,21 @@ public static IEnumerable<Assembly> GetAllReferencedAssemblies(this Assembly cur
{
referencedAssembly = Assembly.Load(reference);
}
catch (FileLoadException)
catch (IOException)
{
// Ignore assemblies which cannot be found or loaded.
continue;
}
catch (FileNotFoundException)

if (locations.Add(referencedAssembly.Location))
{
// Ignore assemblies which cannot be found or loaded.
continue;
assemblyQueue.Add(referencedAssembly);
}
}


if (!locations.Add(referencedAssembly.Location))
continue;

assemblyQueue.Add(referencedAssembly);
if (!recursive)
{
break;
}
}

Expand Down
7 changes: 2 additions & 5 deletions Core/AppBrix/Modules/ModuleBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,10 @@ public abstract class ModuleBase : IModule
/// This is used to determine the order in which the modules are loaded.
/// </summary>
public virtual IEnumerable<Type> Dependencies => this.GetType().Assembly
.GetAllReferencedAssemblies()
.GetReferencedAssemblies(recursive: false)
.Skip(1)
.SelectMany(assembly => assembly.ExportedTypes)
.Where(t => t.IsClass && !t.IsAbstract)
.Where(typeof(IModule).IsAssignableFrom)
.OrderBy(t => t.Namespace)
.ThenBy(t => t.Name);
.Where(t => t.IsClass && !t.IsAbstract && typeof(IModule).IsAssignableFrom(t));
#endregion

#region Public and overriden methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ private IEnumerable<MetadataReference> GetReferences()
var entryAssembly = string.IsNullOrEmpty(entryAssemblyName) ?
Assembly.GetEntryAssembly() :
Assembly.Load(entryAssemblyName);
return entryAssembly.GetAllReferencedAssemblies().Select(x => MetadataReference.CreateFromFile(x.Location));
return entryAssembly.GetReferencedAssemblies(recursive: true).Select(x => MetadataReference.CreateFromFile(x.Location));
}

private ScaffoldedMigration CreateMigration(Type type, string oldMigrationsAssembly, string migrationName)
Expand Down
15 changes: 15 additions & 0 deletions Tests/AppBrix.Tests/DefaultAppTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ public void TestPerformanceRestart()

TestUtils.TestPerformance(() => this.TestPerformanceRestartInternal(app));
}

[Fact, Trait(TestCategories.Category, TestCategories.Performance)]
public void TestPerformanceGetDependencies()
{
TestUtils.TestPerformance(this.TestPerformanceGetDependenciesInternal);
}
#endregion

#region Private methods
Expand Down Expand Up @@ -207,6 +213,15 @@ private void TestPerformanceRestartInternal(IApp app)
app.Restart();
}
}

private void TestPerformanceGetDependenciesInternal()
{
var module = new SimpleEmptyModuleMock();
for (int i = 0; i < 100; i++)
{
var dependencies = module.Dependencies.ToList();
}
}
#endregion

#region Private fields and constants
Expand Down
13 changes: 13 additions & 0 deletions Tests/AppBrix.Tests/Mocks/SimpleEmptyModuleMock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) MarinAtanasov. All rights reserved.
// Licensed under the MIT License (MIT). See License.txt in the project root for license information.
//
using AppBrix.Modules;
using System;
using System.Linq;

namespace AppBrix.Tests.Mocks
{
internal sealed class SimpleEmptyModuleMock : ModuleBase
{
}
}

0 comments on commit bd1e2f3

Please sign in to comment.