Browse Source

Add default repositories for EF core.

pull/81/head
Halil İbrahim Kalkan 9 years ago
parent
commit
2c5bb6fe5d
  1. 6
      src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/AbpDeskConsoleDemoModule.cs
  2. 2
      src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs
  3. 17
      src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDefaultDbContextFactory.cs
  4. 14
      src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs
  5. 8
      src/AbpDesk/AbpDesk.UI/AppModule.cs
  6. 30
      src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs
  7. 4
      src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  8. 23
      src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DbContextHelper.cs
  9. 38
      src/Volo.Abp/Volo/Abp/Domain/Entities/EntityHelper.cs
  10. 3
      src/Volo.Abp/Volo/Abp/Domain/Repositories/IRepository.cs
  11. 2
      src/Volo.Abp/Volo/Abp/Modularity/AbpModule.cs
  12. 38
      src/Volo.Abp/Volo/Abp/Reflection/ReflectionHelper.cs
  13. 1
      src/Volo.DependencyInjection/Microsoft/Extensions/DependencyInjection/ServiceCollectionRegistrationExtensions.cs
  14. 1
      test/AbpDesk/AbpDesk.Application.Tests/AbpDesk/AbpDeskApplicationTestModule.cs
  15. 2
      test/AbpDesk/AbpDesk.Application.Tests/AbpDesk/Tickets/TicketAppService_Tests.cs

6
src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/AbpDeskConsoleDemoModule.cs

@ -1,4 +1,5 @@
using AbpDesk.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
@ -9,6 +10,11 @@ namespace AbpDesk.ConsoleDemo
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AbpDeskDbContext>(options =>
{
options.UseSqlServer("Server=localhost;Database=AbpDesk;Trusted_Connection=True;");
});
services.AddAssemblyOf<AbpDeskConsoleDemoModule>();
}
}

2
src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs

@ -6,6 +6,8 @@ namespace AbpDesk.EntityFrameworkCore
{
public class AbpDeskDbContext : AbpDbContext<AbpDeskDbContext>
{
public DbSet<Ticket> Tickets { get; set; }
public AbpDeskDbContext(DbContextOptions<AbpDeskDbContext> options)
: base(options)
{

17
src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDefaultDbContextFactory.cs

@ -0,0 +1,17 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace AbpDesk.EntityFrameworkCore
{
/* This class is needed for EF Core command line tooling */
public class AbpDeskDefaultDbContextFactory : IDbContextFactory<AbpDeskDbContext>
{
public AbpDeskDbContext Create(DbContextFactoryOptions options)
{
var builder = new DbContextOptionsBuilder<AbpDeskDbContext>();
builder.UseSqlServer("Server=localhost;Database=AbpDesk;Trusted_Connection=True;");
return new AbpDeskDbContext(builder.Options);
}
}
}

14
src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs

@ -1,9 +1,5 @@
using AbpDesk.Tickets;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.Abp.Repositories.EntityFrameworkCore;
namespace AbpDesk.EntityFrameworkCore
{
@ -13,13 +9,7 @@ namespace AbpDesk.EntityFrameworkCore
public override void ConfigureServices(IServiceCollection services)
{
services.AddAssemblyOf<AbpDeskEntityFrameworkCoreModule>();
services.AddTransient<IRepository<Ticket, int>, EfCoreRepository<AbpDeskDbContext, Ticket, int>>();
//services.AddDbContext<AbpDeskDbContext>(options =>
//{
// options.UseSqlServer("Server=localhost;Database=AbpDesk;Trusted_Connection=True;");
//});
services.AddDefaultEfCoreRepositories<AbpDeskDbContext>();
}
}
}

8
src/AbpDesk/AbpDesk.UI/AppModule.cs

@ -1,6 +1,7 @@
using AbpDesk.EntityFrameworkCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore.Modularity;
@ -9,13 +10,18 @@ using Volo.Abp.Modularity;
namespace AbpDesk
{
//TODO: Rename project to AbpDesk.Web.Mvc
//TODO: Rename project to AbpDesk.Web.Mvc & rename to AbpDeskWebAppModule
[DependsOn(typeof(AbpAspNetCoreMvcModule), typeof(AbpDeskApplicationModule), typeof(AbpDeskEntityFrameworkCoreModule))]
public class AppModule : AbpModule
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AbpDeskDbContext>(options =>
{
options.UseSqlServer("Server=localhost;Database=AbpDesk;Trusted_Connection=True;");
});
services.AddMvc();
}

30
src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs

@ -0,0 +1,30 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Repositories.EntityFrameworkCore;
namespace Microsoft.Extensions.DependencyInjection
{
public static class AbpEfCoreServiceCollectionExtensions
{
public static IServiceCollection AddDefaultEfCoreRepositories<TDbContext>(this IServiceCollection services)
where TDbContext : AbpDbContext<TDbContext>
{
//TODO: Add options to use a provided type as default repository.
var dbContextType = typeof(TDbContext);
foreach (var entityType in DbContextHelper.GetEntityTypes(dbContextType))
{
var primaryKeyType = EntityHelper.GetPrimaryKeyType(entityType);
var repositoryInterfaceType = typeof(IRepository<,>).MakeGenericType(entityType, primaryKeyType);
var repositoryImplementationType = typeof(EfCoreRepository<,,>).MakeGenericType(dbContextType, entityType, primaryKeyType);
services.TryAddTransient(repositoryInterfaceType, repositoryImplementationType);
}
return services;
}
}
}

4
src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

@ -2,10 +2,10 @@
namespace Volo.Abp.EntityFrameworkCore
{
public class AbpDbContext<TDbContext> : DbContext
public abstract class AbpDbContext<TDbContext> : DbContext
where TDbContext : DbContext
{
public AbpDbContext(DbContextOptions<TDbContext> options)
protected AbpDbContext(DbContextOptions<TDbContext> options)
: base(options)
{

23
src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DbContextHelper.cs

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Reflection;
namespace Volo.Abp.EntityFrameworkCore
{
internal static class DbContextHelper
{
public static IEnumerable<Type> GetEntityTypes(Type dbContextType)
{
return
from property in dbContextType.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance)
where
ReflectionHelper.IsAssignableToGenericType(property.PropertyType, typeof(DbSet<>)) &&
ReflectionHelper.IsAssignableToGenericType(property.PropertyType.GenericTypeArguments[0], typeof(IEntity<>))
select property.PropertyType.GenericTypeArguments[0];
}
}
}

38
src/Volo.Abp/Volo/Abp/Domain/Entities/EntityHelper.cs

@ -0,0 +1,38 @@
using System;
using System.Reflection;
using Volo.Abp.Reflection;
namespace Volo.Abp.Domain.Entities
{
/// <summary>
/// Some helper methods for entities.
/// </summary>
public static class EntityHelper
{
public static bool IsEntity(Type type)
{
return ReflectionHelper.IsAssignableToGenericType(type, typeof (IEntity<>));
}
public static Type GetPrimaryKeyType<TEntity>()
{
return GetPrimaryKeyType(typeof (TEntity));
}
/// <summary>
/// Gets primary key type of given entity type
/// </summary>
public static Type GetPrimaryKeyType(Type entityType)
{
foreach (var interfaceType in entityType.GetTypeInfo().GetInterfaces())
{
if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof (IEntity<>))
{
return interfaceType.GenericTypeArguments[0];
}
}
throw new AbpException("Can not find primary key type of given entity type: " + entityType + ". Be sure that this entity type implements " + typeof(IEntity<>).AssemblyQualifiedName);
}
}
}

3
src/Volo.Abp/Volo/Abp/Domain/Repositories/IRepository.cs

@ -1,12 +1,13 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
using Volo.DependencyInjection;
namespace Volo.Abp.Domain.Repositories
{
//TODO: Didn't get all members from ABP 1.x
public interface IRepository<TEntity, TPrimaryKey> : IRepositoryMarker
public interface IRepository<TEntity, TPrimaryKey> : IRepositoryMarker, ITransientDependency
where TEntity : class, IEntity<TPrimaryKey>
{
/// <summary>

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

@ -4,6 +4,8 @@ namespace Volo.Abp.Modularity
{
public abstract class AbpModule : IAbpModule, IOnApplicationInitialization
{
//TODO: Add a OnBeforeConfigureServices method.
public virtual void ConfigureServices(IServiceCollection services)
{

38
src/Volo.Abp/Volo/Abp/Reflection/ReflectionHelper.cs

@ -0,0 +1,38 @@
using System;
using System.Reflection;
namespace Volo.Abp.Reflection
{
public static class ReflectionHelper
{
/// <summary>
/// Checks whether <paramref name="givenType"/> implements/inherits <paramref name="genericType"/>.
/// </summary>
/// <param name="givenType">Type to check</param>
/// <param name="genericType">Generic type</param>
public static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
var givenTypeInfo = givenType.GetTypeInfo();
if (givenTypeInfo.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
{
return true;
}
foreach (var interfaceType in givenTypeInfo.GetInterfaces())
{
if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == genericType)
{
return true;
}
}
if (givenTypeInfo.BaseType == null)
{
return false;
}
return IsAssignableToGenericType(givenTypeInfo.BaseType, genericType);
}
}
}

1
src/Volo.DependencyInjection/Microsoft/Extensions/DependencyInjection/ServiceCollectionRegistrationExtensions.cs

@ -11,6 +11,7 @@ namespace Microsoft.Extensions.DependencyInjection
public static class ServiceCollectionRegistrationExtensions
{
//TODO: Check if assembly/type is added before or add TryAdd versions of them?
//TODO: Return IServiceCollection from all methods
public static void AddAssemblyOf<T>(this IServiceCollection services)
{

1
test/AbpDesk/AbpDesk.Application.Tests/AbpDesk/AbpDeskApplicationTestModule.cs

@ -11,6 +11,7 @@ namespace AbpDesk
public override void ConfigureServices(IServiceCollection services)
{
services.AddEntityFrameworkInMemoryDatabase();
services.AddDbContext<AbpDeskDbContext>(options =>
{
options.UseInMemoryDatabase();

2
test/AbpDesk/AbpDesk.Application.Tests/AbpDesk/Tickets/TicketAppService_Tests.cs

@ -22,7 +22,7 @@ namespace AbpDesk.Tickets
//Assert
result.Items.Count.ShouldBeGreaterThan(0);
result.Items.Count.ShouldBe(1);
}
}
}

Loading…
Cancel
Save