Browse Source

Improvement on modularity and DI.

pull/81/head
Halil İbrahim Kalkan 9 years ago
parent
commit
900a5bd667
  1. 14
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/AbpApplicationBuilderExtensions.cs
  2. 4
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/AbpAspNetCoreModule.cs
  3. 4
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/AbpServiceCollectionExtensions.cs
  4. 23
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/Builder/AspNetConfigurationContext.cs
  5. 7
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/Builder/IConfigureAspNet.cs
  6. 27
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/Modularity/ApplicationInitializationContextExtensions.cs
  7. 21
      src/Volo.Abp.AspNetCore/Abp/AspNetCore/Modularity/AspNetCoreModuleInitializer.cs
  8. 1
      src/Volo.Abp/Abp/AbpApplication.cs
  9. 22
      src/Volo.Abp/Abp/AbpServiceCollectionExtensions.cs
  10. 4
      src/Volo.Abp/Abp/Modularity/AbpModule.cs
  11. 14
      src/Volo.Abp/Abp/Modularity/ApplicationInitializationContext.cs
  12. 17
      src/Volo.Abp/Abp/Modularity/DefaultModuleInitializer.cs
  13. 7
      src/Volo.Abp/Abp/Modularity/IOnApplicationInitialization.cs
  14. 7
      src/Volo.Abp/Abp/Modularity/IOnApplicationInitialize.cs
  15. 45
      src/Volo.DependencyInjection/DependencyInjection/CommonServiceCollectionExtensions.cs
  16. 7
      src/Volo.DependencyInjection/DependencyInjection/IObjectAccessor.cs
  17. 17
      src/Volo.DependencyInjection/DependencyInjection/ObjectAccessor.cs
  18. 4
      src/Volo.DependencyInjection/DependencyInjection/ServiceCollectionRegistrationExtensions.cs
  19. 28
      test/Apps/AspNetCoreDemo/AppModule.cs
  20. 4
      test/Apps/AspNetCoreDemo/Startup.cs
  21. 2
      test/Volo.Abp.Tests/Modularity/IndependentEmptyModule.cs
  22. 28
      test/Volo.DependencyInjection.Tests/AbpConventionalDependencyInjectionExtensions_Tests.cs

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

@ -6,18 +6,10 @@ namespace Microsoft.AspNetCore.Builder
{
public static class AbpApplicationBuilderExtensions
{
public static void InitializeAbpApplication(this IApplicationBuilder app) //TODO: Simply rename to InitializeApplication?
public static void InitializeApplication(this IApplicationBuilder app)
{
var abpApplication = app.ApplicationServices.GetRequiredService<AbpApplication>();
app.ApplicationServices.GetRequiredService<ApplicationBuilderAccessor>().App = app;
abpApplication.Initialize(app.ApplicationServices);
app.ApplicationServices.GetRequiredService<ObjectAccessor<IApplicationBuilder>>().Object = app;
app.ApplicationServices.GetRequiredService<AbpApplication>().Initialize(app.ApplicationServices);
}
}
public class ApplicationBuilderAccessor : ISingletonDependency
{
public IApplicationBuilder App { get; set; }
}
}

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

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.DependencyInjection;
@ -8,6 +9,7 @@ namespace Volo.Abp.AspNetCore
{
public void ConfigureServices(IServiceCollection services)
{
services.AddObjectAccessor<IApplicationBuilder>();
services.AddAssemblyOf<AbpAspNetCoreModule>();
}
}

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

@ -6,10 +6,10 @@ 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?
public static AbpApplication AddApplication<TStartupModule>(this IServiceCollection services)
where TStartupModule : IAbpModule
{
AbpApplication.Create<TStartupModule>(services);
return AbpApplication.Create<TStartupModule>(services);
}
}
}

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

@ -1,23 +0,0 @@
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

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

27
src/Volo.Abp.AspNetCore/Abp/AspNetCore/Modularity/ApplicationInitializationContextExtensions.cs

@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.Modularity;
using Volo.DependencyInjection;
namespace Volo.Abp.AspNetCore.Modularity
{
public static class ApplicationInitializationContextExtensions
{
public static IApplicationBuilder GetApplicationBuilder(this ApplicationInitializationContext context)
{
return context.ServiceProvider.GetRequiredService<IObjectAccessor<IApplicationBuilder>>().Object;
}
public static IHostingEnvironment GetEnvironment(this ApplicationInitializationContext context)
{
return context.ServiceProvider.GetRequiredService<IHostingEnvironment>();
}
public static ILoggerFactory GetLoggerFactory(this ApplicationInitializationContext context)
{
return context.ServiceProvider.GetRequiredService<ILoggerFactory>();
}
}
}

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

@ -1,21 +0,0 @@
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);
}
}
}

1
src/Volo.Abp/Abp/AbpApplication.cs

@ -1,6 +1,7 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.DependencyInjection;
namespace Volo.Abp
{

22
src/Volo.Abp/Abp/AbpServiceCollectionExtensions.cs

@ -1,6 +1,4 @@
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Modularity;
@ -8,24 +6,6 @@ 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());

4
src/Volo.Abp/Abp/Modularity/AbpModule.cs

@ -2,14 +2,14 @@
namespace Volo.Abp.Modularity
{
public abstract class AbpModule : IAbpModule, IOnApplicationInitialize
public abstract class AbpModule : IAbpModule, IOnApplicationInitialization
{
public virtual void ConfigureServices(IServiceCollection services)
{
}
public virtual void OnApplicationInitialize()
public virtual void OnApplicationInitialization(ApplicationInitializationContext context)
{
}

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

@ -0,0 +1,14 @@
using System;
namespace Volo.Abp.Modularity
{
public class ApplicationInitializationContext
{
public IServiceProvider ServiceProvider { get; set; }
public ApplicationInitializationContext(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
}
}

17
src/Volo.Abp/Abp/Modularity/DefaultModuleInitializer.cs

@ -1,10 +1,23 @@
namespace Volo.Abp.Modularity
using System;
namespace Volo.Abp.Modularity
{
public class DefaultModuleInitializer : IModuleInitializer
{
private readonly IServiceProvider _serviceProvider;
public DefaultModuleInitializer(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Initialize(IAbpModule module)
{
(module as IOnApplicationInitialize)?.OnApplicationInitialize();
var context = new ApplicationInitializationContext(
_serviceProvider
);
(module as IOnApplicationInitialization)?.OnApplicationInitialization(context);
}
}
}

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

@ -0,0 +1,7 @@
namespace Volo.Abp.Modularity
{
public interface IOnApplicationInitialization
{
void OnApplicationInitialization(ApplicationInitializationContext context);
}
}

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

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

45
src/Volo.DependencyInjection/DependencyInjection/CommonServiceCollectionExtensions.cs

@ -0,0 +1,45 @@
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.DependencyInjection
{
public static class CommonServiceCollectionExtensions
{
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;
}
public static ObjectAccessor<T> AddObjectAccessor<T>(this IServiceCollection services)
{
return services.AddObjectAccessor(new ObjectAccessor<T>());
}
public static ObjectAccessor<T> AddObjectAccessor<T>(this IServiceCollection services, T obj)
{
return services.AddObjectAccessor(new ObjectAccessor<T>(obj));
}
public static ObjectAccessor<T> AddObjectAccessor<T>(this IServiceCollection services, ObjectAccessor<T> accessor)
{
services.AddSingleton(typeof(IObjectAccessor<T>), accessor);
services.AddSingleton(typeof(ObjectAccessor<T>), accessor);
return accessor;
}
}
}

7
src/Volo.DependencyInjection/DependencyInjection/IObjectAccessor.cs

@ -0,0 +1,7 @@
namespace Volo.DependencyInjection
{
public interface IObjectAccessor<T>
{
T Object { get; }
}
}

17
src/Volo.DependencyInjection/DependencyInjection/ObjectAccessor.cs

@ -0,0 +1,17 @@
namespace Volo.DependencyInjection
{
public class ObjectAccessor<T> : IObjectAccessor<T>
{
public T Object { get; set; }
public ObjectAccessor()
{
}
public ObjectAccessor(T obj)
{
Object = obj;
}
}
}

4
src/Volo.DependencyInjection/DependencyInjection/AbpConventionalDependencyInjectionExtensions.cs → src/Volo.DependencyInjection/DependencyInjection/ServiceCollectionRegistrationExtensions.cs

@ -8,7 +8,7 @@ using Volo.Internal;
namespace Volo.DependencyInjection
{
public static class AbpConventionalDependencyInjectionExtensions
public static class ServiceCollectionRegistrationExtensions
{
//TODO: Check if assembly/type is added before or add TryAdd versions of them?
@ -58,7 +58,7 @@ namespace Volo.DependencyInjection
}
}
}
private static List<Type> FindServiceTypes(Type type)
{
var customExposedServices = type.GetTypeInfo().GetCustomAttributes().OfType<IExposedServiceTypesProvider>().SelectMany(p => p.GetExposedServiceTypes()).ToList();

28
test/Apps/AspNetCoreDemo/AppModule.cs

@ -1,32 +1,28 @@
using Microsoft.AspNetCore.Builder;
using Volo.Abp.AspNetCore;
using Volo.Abp.Modularity;
using Volo.Abp.AspNetCore.Modularity;
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;
using Microsoft.AspNetCore.Http;
namespace AspNetCoreDemo
{
[DependsOn(typeof(AbpAspNetCoreModule))]
public class AppModule : IAbpModule, IConfigureAspNet
public class AppModule : AbpModule
{
public void ConfigureServices(IServiceCollection services)
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
}
var app = context.GetApplicationBuilder();
public void Configure(AspNetConfigurationContext context)
{
context.LoggerFactory.AddConsole();
context.GetLoggerFactory().AddConsole();
if (context.Environment.IsDevelopment())
if (context.GetEnvironment().IsDevelopment())
{
context.App.UseDeveloperExceptionPage();
app.UseDeveloperExceptionPage();
}
context.App.Run(async (ctx) =>
app.Run(async (ctx) =>
{
await ctx.Response.WriteAsync("Hello World 3!");
});

4
test/Apps/AspNetCoreDemo/Startup.cs

@ -9,12 +9,12 @@ namespace AspNetCoreDemo
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAbpApplication<AppModule>();
services.AddApplication<AppModule>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.InitializeAbpApplication();
app.InitializeApplication();
}
}
}

2
test/Volo.Abp.Tests/Modularity/IndependentEmptyModule.cs

@ -14,7 +14,7 @@ namespace Volo.Abp.Tests.Modularity
ConfigureServicesIsCalled = true;
}
public override void OnApplicationInitialize()
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
OnApplicationInitializeIsCalled = true;
}

28
test/Volo.DependencyInjection.Tests/AbpConventionalDependencyInjectionExtensions_Tests.cs

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit;
namespace Volo.DependencyInjection.Tests
@ -52,6 +53,28 @@ namespace Volo.DependencyInjection.Tests
_services.ShouldNotContain(typeof(MyServiceWithExposeList));
}
[Fact]
public void AddObjectAccessor_Test()
{
//Arrange
var obj = new MyEmptyClass();
//Act
var accessor = _services.AddObjectAccessor<MyEmptyClass>();
accessor.Object = obj;
//Assert
_services.GetSingletonInstance<IObjectAccessor<MyEmptyClass>>().Object.ShouldBe(obj);
_services.GetSingletonInstance<ObjectAccessor<MyEmptyClass>>().Object.ShouldBe(obj);
var serviceProvider = _services.BuildServiceProvider();
serviceProvider.GetRequiredService<IObjectAccessor<MyEmptyClass>>().Object.ShouldBe(obj);
serviceProvider.GetRequiredService<ObjectAccessor<MyEmptyClass>>().Object.ShouldBe(obj);
}
public class MyTransientClass : ITransientDependency
{
@ -82,5 +105,10 @@ namespace Volo.DependencyInjection.Tests
{
}
public class MyEmptyClass
{
}
}
}

Loading…
Cancel
Save