Introduce AdditionalModuleAssemblyAttribute to define additional assemblies to be part of a module

pull/17026/head
Halil İbrahim Kalkan 2 years ago
parent 13fe1e6d7b
commit d46ba3463f

@ -125,7 +125,7 @@ public static class ApplicationPartSorter
var moduleDependedAssemblies = moduleDescriptor
.Dependencies
.Select(d => d.Assembly)
.SelectMany(d => d.AllAssemblies)
.ToArray();
return partManager.ApplicationParts
@ -161,6 +161,6 @@ public static class ApplicationPartSorter
{
return moduleContainer
.Modules
.FirstOrDefault(m => m.Assembly == assembly);
.FirstOrDefault(m => m.AllAssemblies.Contains(assembly));
}
}

@ -69,7 +69,7 @@ public static class AbpRegistrationBuilderExtensions
where TActivatorData : ReflectionActivatorData
{
// Enable Property Injection only for types in an assembly containing an AbpModule and without a DisablePropertyInjection attribute on class or properties.
if (moduleContainer.Modules.Any(m => m.Assembly == implementationType.Assembly) &&
if (moduleContainer.Modules.Any(m => m.AllAssemblies.Contains(implementationType.Assembly)) &&
implementationType.GetCustomAttributes(typeof(DisablePropertyInjectionAttribute), true).IsNullOrEmpty())
{
registrationBuilder = registrationBuilder.PropertiesAutowired(new AbpPropertySelector(false));

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
@ -11,6 +12,8 @@ public class AbpModuleDescriptor : IAbpModuleDescriptor
public Type Type { get; }
public Assembly Assembly { get; }
public List<Assembly> AllAssemblies { get; }
public IAbpModule Instance { get; }
@ -26,6 +29,7 @@ public class AbpModuleDescriptor : IAbpModuleDescriptor
{
Check.NotNull(type, nameof(type));
Check.NotNull(instance, nameof(instance));
AbpModule.CheckAbpModuleType(type);
if (!type.GetTypeInfo().IsAssignableFrom(instance.GetType()))
{
@ -34,6 +38,7 @@ public class AbpModuleDescriptor : IAbpModuleDescriptor
Type = type;
Assembly = type.Assembly;
AllAssemblies = CreateAllAssembliesList(type);
Instance = instance;
IsLoadedAsPlugIn = isLoadedAsPlugIn;
@ -49,4 +54,25 @@ public class AbpModuleDescriptor : IAbpModuleDescriptor
{
return $"[AbpModuleDescriptor {Type.FullName}]";
}
private static List<Assembly> CreateAllAssembliesList(Type moduleType)
{
var assemblies = new List<Assembly>();
var additionalAssemblyDescriptors = moduleType
.GetCustomAttributes()
.OfType<IAdditionalModuleAssemblyProvider>();
foreach (var descriptor in additionalAssemblyDescriptors)
{
foreach (var assembly in descriptor.GetAssemblies())
{
assemblies.AddIfNotContains(assembly);
}
}
assemblies.Add(moduleType.Assembly);
return assemblies;
}
}

@ -0,0 +1,24 @@
using System;
using System.Linq;
using System.Reflection;
namespace Volo.Abp.Modularity;
/// <summary>
/// Used to define additional assemblies for a module.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class AdditionalModuleAssemblyAttribute : Attribute, IAdditionalModuleAssemblyProvider
{
public Type[] TypesInAssemblies { get; }
public AdditionalModuleAssemblyAttribute(params Type[]? typesInAssemblies)
{
TypesInAssemblies = typesInAssemblies ?? Type.EmptyTypes;
}
public virtual Assembly[] GetAssemblies()
{
return TypesInAssemblies.Select(t => t.Assembly).Distinct().ToArray();
}
}

@ -1,5 +1,4 @@
using System;
using JetBrains.Annotations;
namespace Volo.Abp.Modularity;
@ -9,12 +8,11 @@ namespace Volo.Abp.Modularity;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class DependsOnAttribute : Attribute, IDependedTypesProvider
{
[NotNull]
public Type[] DependedTypes { get; }
public DependsOnAttribute(params Type[]? dependedTypes)
{
DependedTypes = dependedTypes ?? new Type[0];
DependedTypes = dependedTypes ?? Type.EmptyTypes;
}
public virtual Type[] GetDependedTypes()

@ -6,13 +6,36 @@ namespace Volo.Abp.Modularity;
public interface IAbpModuleDescriptor
{
/// <summary>
/// Type of the module class.
/// </summary>
Type Type { get; }
/// <summary>
/// Main assembly that defines the module <see cref="Type"/>.
/// </summary>
Assembly Assembly { get; }
/// <summary>
/// All the assemblies of the module.
/// Includes the main <see cref="Assembly"/> and other assemblies defined
/// on the module <see cref="Type"/> using the <see cref="AdditionalModuleAssemblyAttribute"/> attribute.
/// </summary>
List<Assembly> AllAssemblies { get; }
/// <summary>
/// The instance of the module class (singleton).
/// </summary>
IAbpModule Instance { get; }
/// <summary>
/// Is this module loaded as a plug-in?
/// </summary>
bool IsLoadedAsPlugIn { get; }
/// <summary>
/// Modules on which this module depends on.
/// A module can depend on another module using the <see cref="DependsOnAttribute"/> attribute.
/// </summary>
IReadOnlyList<IAbpModuleDescriptor> Dependencies { get; }
}

@ -0,0 +1,8 @@
using System.Reflection;
namespace Volo.Abp.Modularity;
public interface IAdditionalModuleAssemblyProvider
{
Assembly[] GetAssemblies();
}

@ -21,9 +21,14 @@ public class ModuleLoader_Tests
modules.Length.ShouldBe(2);
modules[0].Type.ShouldBe(typeof(IndependentEmptyModule));
modules[1].Type.ShouldBe(typeof(MyStartupModule));
modules[1].Assembly.ShouldBe(typeof(MyStartupModule).Assembly);
modules[1].AllAssemblies.Count.ShouldBe(2);
modules[1].AllAssemblies[0].ShouldBe(typeof(IAbpApplication).Assembly);
modules[1].AllAssemblies[1].ShouldBe(typeof(MyStartupModule).Assembly);
}
[DependsOn(typeof(IndependentEmptyModule))]
[AdditionalModuleAssembly(typeof(IAbpApplication))]
public class MyStartupModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)

Loading…
Cancel
Save