Browse Source

Improvement on modularity and DI.

pull/81/head
Halil İbrahim Kalkan 10 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 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<ObjectAccessor<IApplicationBuilder>>().Object = app;
app.ApplicationServices.GetRequiredService<AbpApplication>().Initialize(app.ApplicationServices);
app.ApplicationServices.GetRequiredService<ApplicationBuilderAccessor>().App = app;
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.Abp.Modularity;
using Volo.DependencyInjection; using Volo.DependencyInjection;
@ -8,6 +9,7 @@ namespace Volo.Abp.AspNetCore
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddObjectAccessor<IApplicationBuilder>();
services.AddAssemblyOf<AbpAspNetCoreModule>(); 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? //TODO: Decide to move ABP?
public static class AbpServiceCollectionExtensions 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 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 System;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.DependencyInjection;
namespace Volo.Abp namespace Volo.Abp
{ {

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

@ -1,6 +1,4 @@
using System; using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -8,24 +6,6 @@ namespace Volo.Abp
{ {
public static class AbpServiceCollectionExtensions 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) internal static void AddCoreAbpServices(this IServiceCollection services)
{ {
services.TryAddSingleton<IModuleLoader>(new ModuleLoader()); services.TryAddSingleton<IModuleLoader>(new ModuleLoader());

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

@ -2,14 +2,14 @@
namespace Volo.Abp.Modularity 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 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 public class DefaultModuleInitializer : IModuleInitializer
{ {
private readonly IServiceProvider _serviceProvider;
public DefaultModuleInitializer(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Initialize(IAbpModule module) 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 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? //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) private static List<Type> FindServiceTypes(Type type)
{ {
var customExposedServices = type.GetTypeInfo().GetCustomAttributes().OfType<IExposedServiceTypesProvider>().SelectMany(p => p.GetExposedServiceTypes()).ToList(); 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.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore; using Microsoft.AspNetCore.Http;
using Volo.Abp.AspNetCore.Builder;
using Volo.Abp.Modularity;
namespace AspNetCoreDemo namespace AspNetCoreDemo
{ {
[DependsOn(typeof(AbpAspNetCoreModule))] [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.GetLoggerFactory().AddConsole();
{
context.LoggerFactory.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!"); await ctx.Response.WriteAsync("Hello World 3!");
}); });

4
test/Apps/AspNetCoreDemo/Startup.cs

@ -9,12 +9,12 @@ namespace AspNetCoreDemo
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddAbpApplication<AppModule>(); services.AddApplication<AppModule>();
} }
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 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; ConfigureServicesIsCalled = true;
} }
public override void OnApplicationInitialize() public override void OnApplicationInitialization(ApplicationInitializationContext context)
{ {
OnApplicationInitializeIsCalled = true; OnApplicationInitializeIsCalled = true;
} }

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

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit; using Xunit;
namespace Volo.DependencyInjection.Tests namespace Volo.DependencyInjection.Tests
@ -52,6 +53,28 @@ namespace Volo.DependencyInjection.Tests
_services.ShouldNotContain(typeof(MyServiceWithExposeList)); _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 public class MyTransientClass : ITransientDependency
{ {
@ -82,5 +105,10 @@ namespace Volo.DependencyInjection.Tests
{ {
} }
public class MyEmptyClass
{
}
} }
} }

Loading…
Cancel
Save