Browse Source

Worked on module system.

pull/81/head
Halil İbrahim Kalkan 9 years ago
parent
commit
81f9931be6
  1. 38
      Volo.Abp.sln
  2. 23
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/AbpApplicationBuilderExtensions.cs
  3. 16
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/AbpAspNetCoreModule.cs
  4. 15
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/AbpServiceCollectionExtensions.cs
  5. 23
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/Builder/AspNetConfigurationContext.cs
  6. 7
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/Builder/IConfigureAspNet.cs
  7. 21
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/Modularity/AspNetCoreModuleInitializer.cs
  8. 19
      src/Volo.Abp.AspNetCore/Properties/AssemblyInfo.cs
  9. 19
      src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.xproj
  10. 16
      src/Volo.Abp.AspNetCore/project.json
  11. 23
      src/Volo.Abp/Abp/AbpApplication.cs
  12. 39
      src/Volo.Abp/Abp/AbpException.cs
  13. 17
      src/Volo.Abp/Abp/AbpKernelModule.cs
  14. 35
      src/Volo.Abp/Abp/AbpServiceCollectionExtensions.cs
  15. 11
      src/Volo.Abp/Abp/IAbpApplication.cs
  16. 25
      src/Volo.Abp/Abp/Modularity/AbpModuleDescriptor.cs
  17. 31
      src/Volo.Abp/Abp/Modularity/DependsOnAttribute.cs
  18. 0
      src/Volo.Abp/Abp/Modularity/IAbpModule.cs
  19. 9
      src/Volo.Abp/Abp/Modularity/IModuleDependencyDescriptor.cs
  20. 9
      src/Volo.Abp/Abp/Modularity/IModuleInitializer.cs
  21. 14
      src/Volo.Abp/Abp/Modularity/IModuleLoader.cs
  22. 7
      src/Volo.Abp/Abp/Modularity/IModuleManager.cs
  23. 143
      src/Volo.Abp/Abp/Modularity/ModuleLoader.cs
  24. 27
      src/Volo.Abp/Abp/Modularity/ModuleManager.cs
  25. 9
      src/Volo.Abp/Modularity/IModuleRunner.cs
  26. 15
      src/Volo.Abp/Modularity/ModuleRunner.cs
  27. 6
      src/Volo.Abp/Volo.Abp.xproj
  28. 4
      src/Volo.Abp/project.json
  29. 12
      src/Volo.CodeAnnotations/CodeAnnotations/CanBeNullAttribute.cs
  30. 20
      src/Volo.CodeAnnotations/CodeAnnotations/Check.cs
  31. 23
      src/Volo.CodeAnnotations/CodeAnnotations/ContractAnnotationAttribute.cs
  32. 14
      src/Volo.CodeAnnotations/CodeAnnotations/ImplicitUseKindFlags.cs
  33. 13
      src/Volo.CodeAnnotations/CodeAnnotations/ImplicitUseTargetFlags.cs
  34. 9
      src/Volo.CodeAnnotations/CodeAnnotations/InvokerParameterNameAttribute.cs
  35. 9
      src/Volo.CodeAnnotations/CodeAnnotations/NoEnumerationAttribute.cs
  36. 12
      src/Volo.CodeAnnotations/CodeAnnotations/NotNullAttribute.cs
  37. 16
      src/Volo.CodeAnnotations/CodeAnnotations/StringFormatMethodAttribute.cs
  38. 34
      src/Volo.CodeAnnotations/CodeAnnotations/UsedImplicitlyAttribute.cs
  39. 19
      src/Volo.CodeAnnotations/Properties/AssemblyInfo.cs
  40. 19
      src/Volo.CodeAnnotations/Volo.CodeAnnotations.xproj
  41. 13
      src/Volo.CodeAnnotations/project.json
  42. 7
      src/Volo.DependencyInjection/DependencyInjection/AbpConventionalDependencyInjectionExtensions.cs
  43. 40
      src/Volo.ExtensionMethods/Collections/Generic/CollectionExtensions.cs
  44. 80
      src/Volo.ExtensionMethods/Collections/Generic/DictionaryExtensions.cs
  45. 65
      src/Volo.ExtensionMethods/Collections/Generic/EnumerableExtensions.cs
  46. 73
      src/Volo.ExtensionMethods/Collections/Generic/ListExtensions.cs
  47. 19
      src/Volo.ExtensionMethods/Properties/AssemblyInfo.cs
  48. 19
      src/Volo.ExtensionMethods/Volo.ExtensionMethods.xproj
  49. 14
      src/Volo.ExtensionMethods/project.json
  50. 35
      test/Apps/AspNetCoreDemo/AppModule.cs
  51. 25
      test/Apps/AspNetCoreDemo/AspNetCoreDemo.xproj
  52. 20
      test/Apps/AspNetCoreDemo/Program.cs
  53. 27
      test/Apps/AspNetCoreDemo/Properties/launchSettings.json
  54. 21
      test/Apps/AspNetCoreDemo/Startup.cs
  55. 48
      test/Apps/AspNetCoreDemo/project.json
  56. 14
      test/Apps/AspNetCoreDemo/web.config
  57. 19
      test/Volo.Abp.AspNetCore.Tests/Properties/AssemblyInfo.cs
  58. 21
      test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.xproj
  59. 21
      test/Volo.Abp.AspNetCore.Tests/project.json
  60. 14
      test/Volo.Abp.Tests/AbpApplication_Tests.cs
  61. 2
      test/Volo.DependencyInjection.Tests/ServiceCollectionShouldlyExtensions.cs

38
Volo.Abp.sln

@ -30,6 +30,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Abp", "Abp", "{37087D1B-369
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AbpTestBase", "test\AbpTestBase\AbpTestBase.xproj", "{1020F5FD-6A97-40C2-AFCA-EBDF641DF111}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Volo.Abp.AspNetCore", "src\Volo.Abp.AspNetCore\Volo.Abp.AspNetCore.xproj", "{02BE03BA-3411-448C-AB61-CB36407CC49A}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Volo.Abp.AspNetCore.Tests", "test\Volo.Abp.AspNetCore.Tests\Volo.Abp.AspNetCore.Tests.xproj", "{B1D860BB-6EC6-4BAE-ADAA-C2AEC2FFB510}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{A3A3B258-B3D5-4FDE-9D84-CAA8CBB70586}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AspNetCoreDemo", "test\Apps\AspNetCoreDemo\AspNetCoreDemo.xproj", "{12E14D95-4ABA-4290-AB1D-CCF5EB158411}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Volo.ExtensionMethods", "src\Volo.ExtensionMethods\Volo.ExtensionMethods.xproj", "{FC889503-0BF4-4959-AC80-F51073787025}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Volo.CodeAnnotations", "src\Volo.CodeAnnotations\Volo.CodeAnnotations.xproj", "{161A6C10-00FF-4348-993F-D19893ABC57C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -56,6 +68,26 @@ Global
{1020F5FD-6A97-40C2-AFCA-EBDF641DF111}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1020F5FD-6A97-40C2-AFCA-EBDF641DF111}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1020F5FD-6A97-40C2-AFCA-EBDF641DF111}.Release|Any CPU.Build.0 = Release|Any CPU
{02BE03BA-3411-448C-AB61-CB36407CC49A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02BE03BA-3411-448C-AB61-CB36407CC49A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02BE03BA-3411-448C-AB61-CB36407CC49A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02BE03BA-3411-448C-AB61-CB36407CC49A}.Release|Any CPU.Build.0 = Release|Any CPU
{B1D860BB-6EC6-4BAE-ADAA-C2AEC2FFB510}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1D860BB-6EC6-4BAE-ADAA-C2AEC2FFB510}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1D860BB-6EC6-4BAE-ADAA-C2AEC2FFB510}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1D860BB-6EC6-4BAE-ADAA-C2AEC2FFB510}.Release|Any CPU.Build.0 = Release|Any CPU
{12E14D95-4ABA-4290-AB1D-CCF5EB158411}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12E14D95-4ABA-4290-AB1D-CCF5EB158411}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12E14D95-4ABA-4290-AB1D-CCF5EB158411}.Release|Any CPU.ActiveCfg = Release|Any CPU
{12E14D95-4ABA-4290-AB1D-CCF5EB158411}.Release|Any CPU.Build.0 = Release|Any CPU
{FC889503-0BF4-4959-AC80-F51073787025}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC889503-0BF4-4959-AC80-F51073787025}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC889503-0BF4-4959-AC80-F51073787025}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC889503-0BF4-4959-AC80-F51073787025}.Release|Any CPU.Build.0 = Release|Any CPU
{161A6C10-00FF-4348-993F-D19893ABC57C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{161A6C10-00FF-4348-993F-D19893ABC57C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{161A6C10-00FF-4348-993F-D19893ABC57C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{161A6C10-00FF-4348-993F-D19893ABC57C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -70,5 +102,11 @@ Global
{D68B762E-2A55-4A9F-9F2F-D4361B0925B0} = {82B41A0A-6068-410F-9C6B-2508CA763E21}
{37087D1B-3693-4E96-983D-A69F210BDE53} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{1020F5FD-6A97-40C2-AFCA-EBDF641DF111} = {82B41A0A-6068-410F-9C6B-2508CA763E21}
{02BE03BA-3411-448C-AB61-CB36407CC49A} = {4C753F64-0C93-4D65-96C2-A40893AFC1E8}
{B1D860BB-6EC6-4BAE-ADAA-C2AEC2FFB510} = {37087D1B-3693-4E96-983D-A69F210BDE53}
{A3A3B258-B3D5-4FDE-9D84-CAA8CBB70586} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{12E14D95-4ABA-4290-AB1D-CCF5EB158411} = {A3A3B258-B3D5-4FDE-9D84-CAA8CBB70586}
{FC889503-0BF4-4959-AC80-F51073787025} = {9A4A646B-CC96-44FB-A717-E50C5C148B54}
{161A6C10-00FF-4348-993F-D19893ABC57C} = {9A4A646B-CC96-44FB-A717-E50C5C148B54}
EndGlobalSection
EndGlobal

23
src/Volo.Abp.AspNetCore/Abp/AspNetCore/AbpApplicationBuilderExtensions.cs

@ -0,0 +1,23 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.DependencyInjection;
namespace Microsoft.AspNetCore.Builder
{
public static class AbpApplicationBuilderExtensions
{
public static void InitializeAbpApplication(this IApplicationBuilder app) //TODO: Simply rename to InitializeApplication?
{
var abpApplication = app.ApplicationServices.GetRequiredService<IAbpApplication>();
app.ApplicationServices.GetRequiredService<ApplicationBuilderAccessor>().App = app;
abpApplication.Initialize(app.ApplicationServices);
}
}
public class ApplicationBuilderAccessor : ISingletonDependency
{
public IApplicationBuilder App { get; set; }
}
}

16
src/Volo.Abp.AspNetCore/Abp/AspNetCore/AbpAspNetCoreModule.cs

@ -0,0 +1,16 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Modularity;
using Volo.Abp.Modularity;
using Volo.DependencyInjection;
namespace Volo.Abp.AspNetCore
{
public class AbpAspNetCoreModule : IAbpModule
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAssemblyOf<AbpAspNetCoreModule>();
services.AddSingleton<IModuleInitializer, AspNetCoreModuleInitializer>();
}
}
}

15
src/Volo.Abp.AspNetCore/Abp/AspNetCore/AbpServiceCollectionExtensions.cs

@ -0,0 +1,15 @@
using Volo.Abp;
using Volo.Abp.Modularity;
namespace Microsoft.Extensions.DependencyInjection
{
//TODO: Decide to move ABP?
public static class AbpServiceCollectionExtensions
{
public static void AddAbpApplication<TStartupModule>(this IServiceCollection services) //TODO: Simply rename to AddApplication?
where TStartupModule : IAbpModule
{
AbpApplication.Create<TStartupModule>(services);
}
}
}

23
src/Volo.Abp.AspNetCore/Abp/AspNetCore/Builder/AspNetConfigurationContext.cs

@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Volo.Abp.AspNetCore.Builder
{
public class AspNetConfigurationContext
{
public IApplicationBuilder App { get; }
public IHostingEnvironment Environment { get; }
public ILoggerFactory LoggerFactory { get; }
public AspNetConfigurationContext(IApplicationBuilder app)
{
App = app;
Environment = app.ApplicationServices.GetRequiredService<IHostingEnvironment>();
LoggerFactory = app.ApplicationServices.GetRequiredService<ILoggerFactory>();
}
}
}

7
src/Volo.Abp.AspNetCore/Abp/AspNetCore/Builder/IConfigureAspNet.cs

@ -0,0 +1,7 @@
namespace Volo.Abp.AspNetCore.Builder
{
public interface IConfigureAspNet
{
void Configure(AspNetConfigurationContext context);
}
}

21
src/Volo.Abp.AspNetCore/Abp/AspNetCore/Modularity/AspNetCoreModuleInitializer.cs

@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Builder;
using Volo.Abp.AspNetCore.Builder;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Modularity
{
public class AspNetCoreModuleInitializer : IModuleInitializer
{
private readonly AspNetConfigurationContext _configurationContext;
public AspNetCoreModuleInitializer(ApplicationBuilderAccessor appAccessor)
{
_configurationContext = new AspNetConfigurationContext(appAccessor.App);
}
public void Initialize(IAbpModule module)
{
(module as IConfigureAspNet)?.Configure(_configurationContext);
}
}
}

19
src/Volo.Abp.AspNetCore/Properties/AssemblyInfo.cs

@ -0,0 +1,19 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Volo.Abp.AspNetCore")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("02be03ba-3411-448c-ab61-cb36407cc49a")]

19
src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.xproj

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>02be03ba-3411-448c-ab61-cb36407cc49a</ProjectGuid>
<RootNamespace>Volo</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

16
src/Volo.Abp.AspNetCore/project.json

@ -0,0 +1,16 @@
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.6.1",
"Volo.Abp": "1.0.0-*",
"Microsoft.AspNetCore.Http.Abstractions": "1.1.0",
"Microsoft.AspNetCore.Hosting.Abstractions": "1.1.0"
},
"frameworks": {
"netstandard1.6": {
"imports": "dnxcore50"
}
}
}

23
src/Volo.Abp/AbpBootstrapper.cs → src/Volo.Abp/Abp/AbpApplication.cs

@ -1,22 +1,23 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Modularity;
namespace Volo.Abp
{
public class AbpApplication : IDisposable
public class AbpApplication : IAbpApplication
{
public Type StartupModuleType { get; }
private readonly IServiceCollection _services;
private IServiceProvider _serviceProvider;
private AbpApplication(Type startupModuleType, IServiceCollection services)
{
StartupModuleType = startupModuleType;
_services = services;
_services.AddCoreAbp();
services.AddSingleton<IAbpApplication>(this);
services.AddCoreAbpServices();
services.GetSingletonInstance<IModuleLoader>().LoadAll(services, StartupModuleType);
}
public static AbpApplication Create<TStartupModule>(IServiceCollection services)
@ -25,23 +26,15 @@ namespace Volo.Abp
return new AbpApplication(typeof(TStartupModule), services);
}
public void Start(IServiceProvider serviceProvider)
public void Initialize(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_serviceProvider.GetRequiredService<IModuleRunner>().Start();
_serviceProvider.GetRequiredService<IModuleManager>().Initialize();
}
public void Dispose()
{
_serviceProvider.GetRequiredService<IModuleRunner>().Stop();
}
}
internal static class AbpServiceCollectionExtensions
{
public static void AddCoreAbp(this IServiceCollection services)
{
services.TryAddSingleton<IModuleRunner, ModuleRunner>();
}
}
}

39
src/Volo.Abp/Abp/AbpException.cs

@ -0,0 +1,39 @@
using System;
namespace Volo.Abp
{
/// <summary>
/// Base exception type for those are thrown by Abp system for Abp specific exceptions.
/// </summary>
public class AbpException : Exception
{
/// <summary>
/// Creates a new <see cref="AbpException"/> object.
/// </summary>
public AbpException()
{
}
/// <summary>
/// Creates a new <see cref="AbpException"/> object.
/// </summary>
/// <param name="message">Exception message</param>
public AbpException(string message)
: base(message)
{
}
/// <summary>
/// Creates a new <see cref="AbpException"/> object.
/// </summary>
/// <param name="message">Exception message</param>
/// <param name="innerException">Inner exception</param>
public AbpException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

17
src/Volo.Abp/Abp/AbpKernelModule.cs

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace Volo.Abp
{
public class AbpKernelModule : IAbpModule
{
public void ConfigureServices(IServiceCollection services)
{
}
}
}

35
src/Volo.Abp/Abp/AbpServiceCollectionExtensions.cs

@ -0,0 +1,35 @@
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Modularity;
namespace Volo.Abp
{
public static class AbpServiceCollectionExtensions
{
public static T GetSingletonInstanceOrNull<T>(this IServiceCollection services)
{
return (T)services
.FirstOrDefault(d => d.ServiceType == typeof(T))
?.ImplementationInstance;
}
public static T GetSingletonInstance<T>(this IServiceCollection services)
{
var service = services.GetSingletonInstanceOrNull<T>();
if (service == null)
{
throw new InvalidOperationException("Could not find singleton service: " + typeof(T).AssemblyQualifiedName);
}
return service;
}
internal static void AddCoreAbpServices(this IServiceCollection services)
{
services.TryAddSingleton<IModuleLoader>(new ModuleLoader());
services.TryAddSingleton<IModuleManager, ModuleManager>();
}
}
}

11
src/Volo.Abp/Abp/IAbpApplication.cs

@ -0,0 +1,11 @@
using System;
namespace Volo.Abp
{
public interface IAbpApplication : IDisposable
{
Type StartupModuleType { get; }
void Initialize(IServiceProvider serviceProvider);
}
}

25
src/Volo.Abp/Abp/Modularity/AbpModuleDescriptor.cs

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Abp.Modularity
{
public class AbpModuleDescriptor
{
public Type Type { get; }
public IAbpModule Instance { get; }
public List<AbpModuleDescriptor> Dependencies { get; }
public AbpModuleDescriptor([NotNull] Type type, [NotNull] IAbpModule instance)
{
Check.NotNull(type, nameof(type));
Check.NotNull(instance, nameof(instance));
Type = type;
Instance = instance;
Dependencies = new List<AbpModuleDescriptor>();
}
}
}

31
src/Volo.Abp/Abp/Modularity/DependsOnAttribute.cs

@ -0,0 +1,31 @@
using System;
namespace Volo.Abp.Modularity
{
/// <summary>
/// Used to define dependencies of an ABP module to other modules.
/// It should be used for a class implements <see cref="IAbpModule"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class DependsOnAttribute : Attribute, IModuleDependencyDescriptor
{
/// <summary>
/// Types of depended modules.
/// </summary>
public Type[] DependedModuleTypes { get; }
/// <summary>
/// Used to define dependencies of an ABP module to other modules.
/// </summary>
/// <param name="dependedModuleTypes">Types of depended modules</param>
public DependsOnAttribute(params Type[] dependedModuleTypes)
{
DependedModuleTypes = dependedModuleTypes;
}
public Type[] GetDependedModuleTypes()
{
return DependedModuleTypes;
}
}
}

0
src/Volo.Abp/Modularity/IAbpModule.cs → src/Volo.Abp/Abp/Modularity/IAbpModule.cs

9
src/Volo.Abp/Abp/Modularity/IModuleDependencyDescriptor.cs

@ -0,0 +1,9 @@
using System;
namespace Volo.Abp.Modularity
{
public interface IModuleDependencyDescriptor
{
Type[] GetDependedModuleTypes();
}
}

9
src/Volo.Abp/Abp/Modularity/IModuleInitializer.cs

@ -0,0 +1,9 @@
using Volo.DependencyInjection;
namespace Volo.Abp.Modularity
{
public interface IModuleInitializer : ISingletonDependency
{
void Initialize(IAbpModule module);
}
}

14
src/Volo.Abp/Abp/Modularity/IModuleLoader.cs

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.DependencyInjection;
namespace Volo.Abp.Modularity
{
public interface IModuleLoader : ISingletonDependency
{
IReadOnlyList<AbpModuleDescriptor> Modules { get; }
void LoadAll(IServiceCollection services, Type startupModuleType);
}
}

7
src/Volo.Abp/Abp/Modularity/IModuleManager.cs

@ -0,0 +1,7 @@
namespace Volo.Abp.Modularity
{
public interface IModuleManager
{
void Initialize();
}
}

143
src/Volo.Abp/Abp/Modularity/ModuleLoader.cs

@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Volo.Collections.Generic;
namespace Volo.Abp.Modularity
{
public class ModuleLoader : IModuleLoader
{
public IReadOnlyList<AbpModuleDescriptor> Modules => _modules.ToImmutableList();
private readonly List<AbpModuleDescriptor> _modules;
public ModuleLoader()
{
_modules = new List<AbpModuleDescriptor>();
}
public virtual void LoadAll(IServiceCollection services, Type startupModuleType)
{
if (_modules.Any())
{
throw new InvalidOperationException($"{nameof(LoadAll)} should be called only once!");
}
FillModules(startupModuleType);
SetModuleDependencies();
ConfigureServices(services);
}
private void SetModuleDependencies()
{
foreach (var module in Modules)
{
SetModuleDependencies(module);
}
}
private void FillModules(Type startupModuleType)
{
foreach (var moduleType in FindAllModuleTypes(startupModuleType).Distinct())
{
_modules.Add(CreateModuleDescriptor(moduleType));
}
}
protected virtual IEnumerable<Type> FindAllModuleTypes(Type startupModuleType)
{
var moduleTypes = new List<Type>();
AddModuleAndDependenciesResursively(moduleTypes, startupModuleType);
moduleTypes.AddIfNotContains(typeof(AbpKernelModule));
return moduleTypes;
}
protected virtual AbpModuleDescriptor CreateModuleDescriptor(Type moduleType)
{
return new AbpModuleDescriptor(moduleType, (IAbpModule)Activator.CreateInstance(moduleType));
}
protected virtual void ConfigureServices(IServiceCollection services)
{
foreach (var module in _modules)
{
module.Instance.ConfigureServices(services);
}
}
protected virtual void AddModuleAndDependenciesResursively(List<Type> moduleTypes, Type moduleType)
{
CheckAbpModuleType(moduleType);
if (moduleTypes.Contains(moduleType))
{
return;
}
moduleTypes.Add(moduleType);
foreach (var dependedModuleType in FindDependedModuleTypes(moduleType))
{
AddModuleAndDependenciesResursively(moduleTypes, dependedModuleType);
}
}
protected virtual List<Type> FindDependedModuleTypes(Type moduleType)
{
CheckAbpModuleType(moduleType);
var dependencies = new List<Type>();
var dependencyDescriptors = moduleType
.GetTypeInfo()
.GetCustomAttributes()
.OfType<IModuleDependencyDescriptor>();
foreach (var descriptor in dependencyDescriptors)
{
foreach (var dependedModuleType in descriptor.GetDependedModuleTypes())
{
dependencies.AddIfNotContains(dependedModuleType);
}
}
return dependencies;
}
protected virtual void SetModuleDependencies(AbpModuleDescriptor module)
{
foreach (var dependedModuleType in FindDependedModuleTypes(module.Type))
{
var dependedModule = _modules.FirstOrDefault(m => m.Type == dependedModuleType);
if (dependedModule == null)
{
throw new AbpException("Could not find a depended module " + dependedModuleType.AssemblyQualifiedName + " for " + module.Type.AssemblyQualifiedName);
}
module.Dependencies.AddIfNotContains(dependedModule);
}
}
protected static void CheckAbpModuleType(Type moduleType)
{
if (!IsAbpModule(moduleType))
{
throw new ArgumentException("Given type is not an ABP module: " + moduleType.AssemblyQualifiedName);
}
}
protected static bool IsAbpModule(Type type)
{
var typeInfo = type.GetTypeInfo();
return
typeInfo.IsClass &&
!typeInfo.IsAbstract &&
!typeInfo.IsGenericType &&
typeof(IAbpModule).GetTypeInfo().IsAssignableFrom(type);
}
}
}

27
src/Volo.Abp/Abp/Modularity/ModuleManager.cs

@ -0,0 +1,27 @@
using System.Collections.Generic;
namespace Volo.Abp.Modularity
{
public class ModuleManager : IModuleManager
{
private readonly IModuleLoader _moduleLoader;
private readonly IEnumerable<IModuleInitializer> _initializers;
public ModuleManager(IModuleLoader moduleLoader, IEnumerable<IModuleInitializer> initializers)
{
_moduleLoader = moduleLoader;
_initializers = initializers;
}
public void Initialize()
{
foreach (var initializer in _initializers)
{
foreach (var module in _moduleLoader.Modules)
{
initializer.Initialize(module.Instance);
}
}
}
}
}

9
src/Volo.Abp/Modularity/IModuleRunner.cs

@ -1,9 +0,0 @@
namespace Volo.Abp.Modularity
{
public interface IModuleRunner
{
void Start();
void Stop();
}
}

15
src/Volo.Abp/Modularity/ModuleRunner.cs

@ -1,15 +0,0 @@
namespace Volo.Abp.Modularity
{
public class ModuleRunner : IModuleRunner
{
public void Start()
{
}
public void Stop()
{
}
}
}

6
src/Volo.Abp/Volo.Abp.xproj

@ -4,18 +4,16 @@
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>fc5f7372-ea60-4052-b943-0ee070221cc1</ProjectGuid>
<RootNamespace>Volo.Abp</RootNamespace>
<RootNamespace>Volo</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
</Project>

4
src/Volo.Abp/project.json

@ -3,7 +3,9 @@
"dependencies": {
"NETStandard.Library": "1.6.1",
"Volo.DependencyInjection": "1.0.0-*"
"Volo.DependencyInjection": "1.0.0-*",
"System.Collections.Immutable": "1.3.0",
"Volo.ExtensionMethods": "1.0.0-*"
},
"frameworks": {

12
src/Volo.CodeAnnotations/CodeAnnotations/CanBeNullAttribute.cs

@ -0,0 +1,12 @@
using System;
namespace JetBrains.Annotations
{
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter |
AttributeTargets.Property | AttributeTargets.Delegate |
AttributeTargets.Field)]
public sealed class CanBeNullAttribute : Attribute
{
}
}

20
src/Volo.CodeAnnotations/CodeAnnotations/Check.cs

@ -0,0 +1,20 @@
using System;
using System.Diagnostics;
namespace JetBrains.Annotations
{
[DebuggerStepThrough]
public static class Check
{
[ContractAnnotation("value:null => halt")]
public static T NotNull<T>(T value, [InvokerParameterName] [NotNull] string parameterName)
{
if (value == null)
{
throw new ArgumentNullException(parameterName);
}
return value;
}
}
}

23
src/Volo.CodeAnnotations/CodeAnnotations/ContractAnnotationAttribute.cs

@ -0,0 +1,23 @@
using System;
namespace JetBrains.Annotations
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public sealed class ContractAnnotationAttribute : Attribute
{
public string Contract { get; private set; }
public bool ForceFullStates { get; private set; }
public ContractAnnotationAttribute([NotNull] string contract)
: this(contract, false)
{
}
public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates)
{
Contract = contract;
ForceFullStates = forceFullStates;
}
}
}

14
src/Volo.CodeAnnotations/CodeAnnotations/ImplicitUseKindFlags.cs

@ -0,0 +1,14 @@
using System;
namespace JetBrains.Annotations
{
[Flags]
public enum ImplicitUseKindFlags
{
Default = Access | Assign | InstantiatedWithFixedConstructorSignature,
Access = 1,
Assign = 2,
InstantiatedWithFixedConstructorSignature = 4,
InstantiatedNoFixedConstructorSignature = 8
}
}

13
src/Volo.CodeAnnotations/CodeAnnotations/ImplicitUseTargetFlags.cs

@ -0,0 +1,13 @@
using System;
namespace JetBrains.Annotations
{
[Flags]
public enum ImplicitUseTargetFlags
{
Default = Itself,
Itself = 1,
Members = 2,
WithMembers = Itself | Members
}
}

9
src/Volo.CodeAnnotations/CodeAnnotations/InvokerParameterNameAttribute.cs

@ -0,0 +1,9 @@
using System;
namespace JetBrains.Annotations
{
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class InvokerParameterNameAttribute : Attribute
{
}
}

9
src/Volo.CodeAnnotations/CodeAnnotations/NoEnumerationAttribute.cs

@ -0,0 +1,9 @@
using System;
namespace JetBrains.Annotations
{
[AttributeUsage(AttributeTargets.Parameter)]
internal sealed class NoEnumerationAttribute : Attribute
{
}
}

12
src/Volo.CodeAnnotations/CodeAnnotations/NotNullAttribute.cs

@ -0,0 +1,12 @@
using System;
namespace JetBrains.Annotations
{
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter |
AttributeTargets.Property | AttributeTargets.Delegate |
AttributeTargets.Field)]
public sealed class NotNullAttribute : Attribute
{
}
}

16
src/Volo.CodeAnnotations/CodeAnnotations/StringFormatMethodAttribute.cs

@ -0,0 +1,16 @@
using System;
namespace JetBrains.Annotations
{
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Delegate)]
public sealed class StringFormatMethodAttribute : Attribute
{
public StringFormatMethodAttribute([NotNull] string formatParameterName)
{
FormatParameterName = formatParameterName;
}
[NotNull]
public string FormatParameterName { get; private set; }
}
}

34
src/Volo.CodeAnnotations/CodeAnnotations/UsedImplicitlyAttribute.cs

@ -0,0 +1,34 @@
using System;
namespace JetBrains.Annotations
{
[AttributeUsage(AttributeTargets.All)]
public sealed class UsedImplicitlyAttribute : Attribute
{
public UsedImplicitlyAttribute()
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
{
}
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
: this(useKindFlags, ImplicitUseTargetFlags.Default)
{
}
public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
: this(ImplicitUseKindFlags.Default, targetFlags)
{
}
public UsedImplicitlyAttribute(
ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
{
UseKindFlags = useKindFlags;
TargetFlags = targetFlags;
}
public ImplicitUseKindFlags UseKindFlags { get; private set; }
public ImplicitUseTargetFlags TargetFlags { get; private set; }
}
}

19
src/Volo.CodeAnnotations/Properties/AssemblyInfo.cs

@ -0,0 +1,19 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Volo.CodeAnnotations")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("161a6c10-00ff-4348-993f-d19893abc57c")]

19
src/Volo.CodeAnnotations/Volo.CodeAnnotations.xproj

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>161a6c10-00ff-4348-993f-d19893abc57c</ProjectGuid>
<RootNamespace>Volo</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

13
src/Volo.CodeAnnotations/project.json

@ -0,0 +1,13 @@
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.6.1"
},
"frameworks": {
"netstandard1.6": {
"imports": "dnxcore50"
}
}
}

7
src/Volo.DependencyInjection/DependencyInjection/AbpConventionalDependencyInjectionExtensions.cs

@ -9,6 +9,13 @@ namespace Volo.DependencyInjection
{
public static class AbpConventionalDependencyInjectionExtensions
{
//TODO: Check if assembly/type is added before or add TryAdd versions of them?
public static void AddAssemblyOf<T>(this IServiceCollection services)
{
services.AddAssembly(typeof(T).GetTypeInfo().Assembly);
}
public static void AddAssembly(this IServiceCollection services, Assembly assembly)
{
services.AddTypes(AssemblyHelper.GetAllTypes(assembly).FilterInjectableTypes().ToArray());

40
src/Volo.ExtensionMethods/Collections/Generic/CollectionExtensions.cs

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Collections.Generic
{
/// <summary>
/// Extension methods for Collections.
/// </summary>
public static class CollectionExtensions
{
/// <summary>
/// Checks whatever given collection object is null or has no item.
/// </summary>
public static bool IsNullOrEmpty<T>([CanBeNull] this ICollection<T> source)
{
return source == null || source.Count <= 0;
}
/// <summary>
/// Adds an item to the collection if it's not already in the collection.
/// </summary>
/// <param name="source">Collection</param>
/// <param name="item">Item to check and add</param>
/// <typeparam name="T">Type of the items in the collection</typeparam>
/// <returns>Returns True if added, returns False if not.</returns>
public static bool AddIfNotContains<T>([NotNull] this ICollection<T> source, T item)
{
Check.NotNull(source, nameof(source));
if (source.Contains(item))
{
return false;
}
source.Add(item);
return true;
}
}
}

80
src/Volo.ExtensionMethods/Collections/Generic/DictionaryExtensions.cs

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
namespace Volo.Collections.Generic
{
/// <summary>
/// Extension methods for Dictionary.
/// </summary>
public static class DictionaryExtensions
{
/// <summary>
/// This method is used to try to get a value in a dictionary if it does exists.
/// </summary>
/// <typeparam name="T">Type of the value</typeparam>
/// <param name="dictionary">The collection object</param>
/// <param name="key">Key</param>
/// <param name="value">Value of the key (or default value if key not exists)</param>
/// <returns>True if key does exists in the dictionary</returns>
internal static bool TryGetValue<T>(this IDictionary<string, object> dictionary, string key, out T value)
{
object valueObj;
if (dictionary.TryGetValue(key, out valueObj) && valueObj is T)
{
value = (T)valueObj;
return true;
}
value = default(T);
return false;
}
/// <summary>
/// Gets a value from the dictionary with given key. Returns default value if can not find.
/// </summary>
/// <param name="dictionary">Dictionary to check and get</param>
/// <param name="key">Key to find the value</param>
/// <typeparam name="TKey">Type of the key</typeparam>
/// <typeparam name="TValue">Type of the value</typeparam>
/// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
{
TValue obj;
return dictionary.TryGetValue(key, out obj) ? obj : default(TValue);
}
/// <summary>
/// Gets a value from the dictionary with given key. Returns default value if can not find.
/// </summary>
/// <param name="dictionary">Dictionary to check and get</param>
/// <param name="key">Key to find the value</param>
/// <param name="factory">A factory method used to create the value if not found in the dictionary</param>
/// <typeparam name="TKey">Type of the key</typeparam>
/// <typeparam name="TValue">Type of the value</typeparam>
/// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TValue> factory)
{
TValue obj;
if (dictionary.TryGetValue(key, out obj))
{
return obj;
}
return dictionary[key] = factory(key);
}
/// <summary>
/// Gets a value from the dictionary with given key. Returns default value if can not find.
/// </summary>
/// <param name="dictionary">Dictionary to check and get</param>
/// <param name="key">Key to find the value</param>
/// <param name="factory">A factory method used to create the value if not found in the dictionary</param>
/// <typeparam name="TKey">Type of the key</typeparam>
/// <typeparam name="TValue">Type of the value</typeparam>
/// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> factory)
{
return dictionary.GetOrAdd(key, k => factory());
}
}
}

65
src/Volo.ExtensionMethods/Collections/Generic/EnumerableExtensions.cs

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Volo.Collections.Generic
{
/// <summary>
/// Extension methods for <see cref="IEnumerable{T}"/>.
/// </summary>
public static class EnumerableExtensions
{
/// <summary>
/// Concatenates the members of a constructed <see cref="IEnumerable{T}"/> collection of type System.String, using the specified separator between each member.
/// This is a shortcut for string.Join(...)
/// </summary>
/// <param name="source">A collection that contains the strings to concatenate.</param>
/// <param name="separator">The string to use as a separator. separator is included in the returned string only if values has more than one element.</param>
/// <returns>A string that consists of the members of values delimited by the separator string. If values has no members, the method returns System.String.Empty.</returns>
public static string JoinAsString(this IEnumerable<string> source, string separator)
{
return string.Join(separator, source);
}
/// <summary>
/// Concatenates the members of a collection, using the specified separator between each member.
/// This is a shortcut for string.Join(...)
/// </summary>
/// <param name="source">A collection that contains the objects to concatenate.</param>
/// <param name="separator">The string to use as a separator. separator is included in the returned string only if values has more than one element.</param>
/// <typeparam name="T">The type of the members of values.</typeparam>
/// <returns>A string that consists of the members of values delimited by the separator string. If values has no members, the method returns System.String.Empty.</returns>
public static string JoinAsString<T>(this IEnumerable<T> source, string separator)
{
return string.Join(separator, source);
}
/// <summary>
/// Filters a <see cref="IEnumerable{T}"/> by given predicate if given condition is true.
/// </summary>
/// <param name="source">Enumerable to apply filtering</param>
/// <param name="condition">A boolean value</param>
/// <param name="predicate">Predicate to filter the enumerable</param>
/// <returns>Filtered or not filtered enumerable based on <paramref name="condition"/></returns>
public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, bool condition, Func<T, bool> predicate)
{
return condition
? source.Where(predicate)
: source;
}
/// <summary>
/// Filters a <see cref="IEnumerable{T}"/> by given predicate if given condition is true.
/// </summary>
/// <param name="source">Enumerable to apply filtering</param>
/// <param name="condition">A boolean value</param>
/// <param name="predicate">Predicate to filter the enumerable</param>
/// <returns>Filtered or not filtered enumerable based on <paramref name="condition"/></returns>
public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, bool condition, Func<T, int, bool> predicate)
{
return condition
? source.Where(predicate)
: source;
}
}
}

73
src/Volo.ExtensionMethods/Collections/Generic/ListExtensions.cs

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
namespace Volo.Collections.Generic
{
/// <summary>
/// Extension methods for <see cref="IList{T}"/>.
/// </summary>
public static class ListExtensions
{
/// <summary>
/// Sort a list by a topological sorting, which consider their dependencies
/// </summary>
/// <typeparam name="T">The type of the members of values.</typeparam>
/// <param name="source">A list of objects to sort</param>
/// <param name="getDependencies">Function to resolve the dependencies</param>
/// <returns></returns>
public static List<T> SortByDependencies<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> getDependencies)
{
/* See: http://www.codeproject.com/Articles/869059/Topological-sorting-in-Csharp
* http://en.wikipedia.org/wiki/Topological_sorting
*/
var sorted = new List<T>();
var visited = new Dictionary<T, bool>();
foreach (var item in source)
{
SortByDependenciesVisit(item, getDependencies, sorted, visited);
}
return sorted;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T">The type of the members of values.</typeparam>
/// <param name="item">Item to resolve</param>
/// <param name="getDependencies">Function to resolve the dependencies</param>
/// <param name="sorted">List with the sortet items</param>
/// <param name="visited">Dictionary with the visited items</param>
private static void SortByDependenciesVisit<T>(T item, Func<T, IEnumerable<T>> getDependencies, List<T> sorted, Dictionary<T, bool> visited)
{
bool inProcess;
var alreadyVisited = visited.TryGetValue(item, out inProcess);
if (alreadyVisited)
{
if (inProcess)
{
throw new ArgumentException("Cyclic dependency found! Item: " + item);
}
}
else
{
visited[item] = true;
var dependencies = getDependencies(item);
if (dependencies != null)
{
foreach (var dependency in dependencies)
{
SortByDependenciesVisit(dependency, getDependencies, sorted, visited);
}
}
visited[item] = false;
sorted.Add(item);
}
}
}
}

19
src/Volo.ExtensionMethods/Properties/AssemblyInfo.cs

@ -0,0 +1,19 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Volo.ExtensionMethods")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("fc889503-0bf4-4959-ac80-f51073787025")]

19
src/Volo.ExtensionMethods/Volo.ExtensionMethods.xproj

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>fc889503-0bf4-4959-ac80-f51073787025</ProjectGuid>
<RootNamespace>Volo</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

14
src/Volo.ExtensionMethods/project.json

@ -0,0 +1,14 @@
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.6.1",
"Volo.CodeAnnotations": "1.0.0-*"
},
"frameworks": {
"netstandard1.6": {
"imports": "dnxcore50"
}
}
}

35
test/Apps/AspNetCoreDemo/AppModule.cs

@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore;
using Volo.Abp.AspNetCore.Builder;
using Volo.Abp.Modularity;
namespace AspNetCoreDemo
{
[DependsOn(typeof(AbpAspNetCoreModule))]
public class AppModule : IAbpModule, IConfigureAspNet
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(AspNetConfigurationContext context)
{
context.LoggerFactory.AddConsole();
if (context.Environment.IsDevelopment())
{
context.App.UseDeveloperExceptionPage();
}
context.App.Run(async (ctx) =>
{
await ctx.Response.WriteAsync("Hello World 3!");
});
}
}
}

25
test/Apps/AspNetCoreDemo/AspNetCoreDemo.xproj

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>12e14d95-4aba-4290-ab1d-ccf5eb158411</ProjectGuid>
<RootNamespace>AspNetCoreDemo</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<DnxInvisibleContent Include="bower.json" />
<DnxInvisibleContent Include=".bowerrc" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet.Web\Microsoft.DotNet.Web.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

20
test/Apps/AspNetCoreDemo/Program.cs

@ -0,0 +1,20 @@
using System.IO;
using Microsoft.AspNetCore.Hosting;
namespace AspNetCoreDemo
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}

27
test/Apps/AspNetCoreDemo/Properties/launchSettings.json

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59980/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"AspNetCoreDemo": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

21
test/Apps/AspNetCoreDemo/Startup.cs

@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace AspNetCoreDemo
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAbpApplication<AppModule>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.InitializeAbpApplication();
}
}
}

48
test/Apps/AspNetCoreDemo/project.json

@ -0,0 +1,48 @@
{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1",
"type": "platform"
},
"Microsoft.AspNetCore.Diagnostics": "1.1.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.1.0",
"Volo.Abp.AspNetCore": "1.0.0-*"
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final"
},
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},
"publishOptions": {
"include": [
"wwwroot",
"web.config"
]
},
"scripts": {
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}
}

14
test/Apps/AspNetCoreDemo/web.config

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
</configuration>

19
test/Volo.Abp.AspNetCore.Tests/Properties/AssemblyInfo.cs

@ -0,0 +1,19 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Volo.Abp.AspNetCore.Tests")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b1d860bb-6ec6-4bae-adaa-c2aec2ffb510")]

21
test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.xproj

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>b1d860bb-6ec6-4bae-adaa-c2aec2ffb510</ProjectGuid>
<RootNamespace>Volo.Abp.AspNetCore.Tests</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

21
test/Volo.Abp.AspNetCore.Tests/project.json

@ -0,0 +1,21 @@
{
"version": "1.0.0-*",
"testRunner": "xunit",
"dependencies": {
"AbpTestBase": "1.0.0-*",
"Volo.Abp.AspNetCore": "1.0.0-*"
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
}
}
}
}

14
test/Volo.Abp.Tests/AbpApplication_Tests.cs

@ -1,6 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Tests.Modularity;
using Volo.DependencyInjection.Tests;
using Xunit;
namespace Volo.Abp.Tests
@ -14,18 +13,7 @@ namespace Volo.Abp.Tests
using (var application = AbpApplication.Create<IndependentEmptyModule>(services))
{
application.Start(services.BuildServiceProvider());
}
}
[Fact]
public void Should_Automatically_Register_Modules()
{
var services = new ServiceCollection();
using (AbpApplication.Create<IndependentEmptyModule>(services))
{
services.ShouldContainSingleton(typeof(IndependentEmptyModule));
application.Initialize(services.BuildServiceProvider());
}
}
}

2
test/Volo.DependencyInjection.Tests/ServiceCollectionShouldlyExtensions.cs

@ -11,6 +11,7 @@ namespace Volo.DependencyInjection.Tests
{
var serviceDescriptor = services.FirstOrDefault(s => s.ServiceType == type);
serviceDescriptor.ShouldNotBeNull();
serviceDescriptor.ImplementationType.ShouldBe(type);
serviceDescriptor.ShouldNotBeNull();
serviceDescriptor.ImplementationFactory.ShouldBeNull();
@ -22,6 +23,7 @@ namespace Volo.DependencyInjection.Tests
{
var serviceDescriptor = services.FirstOrDefault(s => s.ServiceType == type);
serviceDescriptor.ShouldNotBeNull();
serviceDescriptor.ImplementationType.ShouldBe(type);
serviceDescriptor.ShouldNotBeNull();
serviceDescriptor.ImplementationFactory.ShouldBeNull();

Loading…
Cancel
Save