diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain.Shared/ProductManagement/ProductConsts.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain.Shared/ProductManagement/ProductConsts.cs
new file mode 100644
index 0000000000..c6cc028936
--- /dev/null
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain.Shared/ProductManagement/ProductConsts.cs
@@ -0,0 +1,9 @@
+namespace ProductManagement
+{
+ public static class ProductConsts
+ {
+ public const int MaxCodeLength = 32;
+
+ public const int MaxNameLength = 256;
+ }
+}
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement.Domain.csproj b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement.Domain.csproj
index 07c011d408..961598b366 100644
--- a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement.Domain.csproj
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement.Domain.csproj
@@ -8,14 +8,15 @@
+
-
+
-
+
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/Localization/Domain/en.json b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/en.json
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/Localization/Domain/en.json
rename to samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/en.json
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/Localization/Domain/pt-BR.json b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/pt-BR.json
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/Localization/Domain/pt-BR.json
rename to samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/pt-BR.json
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/Localization/Domain/zh-Hans.json b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/zh-Hans.json
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/Localization/Domain/zh-Hans.json
rename to samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/zh-Hans.json
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Product.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Product.cs
new file mode 100644
index 0000000000..15fff0cd69
--- /dev/null
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Product.cs
@@ -0,0 +1,101 @@
+using System;
+using JetBrains.Annotations;
+using Volo.Abp;
+using Volo.Abp.Domain.Entities.Auditing;
+
+namespace ProductManagement
+{
+ public class Product : AuditedAggregateRoot
+ {
+ ///
+ /// A unique value for this product.
+ /// ProductManager ensures the uniqueness of it.
+ /// It can not be changed after creation of the product.
+ ///
+ [NotNull]
+ public string Code { get; private set; }
+
+ [NotNull]
+ public string Name { get; private set; }
+
+ public float Price { get; private set; }
+
+ public int StockCount { get; private set; }
+
+ private Product()
+ {
+ //Default constructor is needed for ORMs.
+ }
+
+ internal Product(
+ Guid id,
+ [NotNull] string code,
+ [NotNull] string name,
+ float price = 0.0f,
+ int stockCount = 0)
+ {
+ Check.NotNullOrWhiteSpace(code, nameof(code));
+
+ if (code.Length >= ProductConsts.MaxCodeLength)
+ {
+ throw new ArgumentException($"Product code can not be longer than {ProductConsts.MaxCodeLength}");
+ }
+
+ Id = id;
+ Code = code;
+ SetName(Check.NotNullOrWhiteSpace(name, nameof(name)));
+ SetPrice(price);
+ SetStockCountInternal(stockCount, triggerEvent: false);
+ }
+
+ public Product SetName([NotNull] string name)
+ {
+ Check.NotNullOrWhiteSpace(name, nameof(name));
+
+ if (name.Length >= ProductConsts.MaxNameLength)
+ {
+ throw new ArgumentException($"Product name can not be longer than {ProductConsts.MaxNameLength}");
+ }
+
+ Name = name;
+ return this;
+ }
+
+ public Product SetPrice(float price)
+ {
+ if (price < 0.0f)
+ {
+ throw new ArgumentException($"{nameof(price)} can not be less than 0.0!");
+ }
+
+ Price = price;
+ return this;
+ }
+
+ public Product SetStockCount(int stockCount)
+ {
+ return SetStockCountInternal(stockCount);
+ }
+
+ private Product SetStockCountInternal(int stockCount, bool triggerEvent = true)
+ {
+ if (StockCount < 0.0f)
+ {
+ throw new ArgumentException($"{nameof(stockCount)} can not be less than 0!");
+ }
+
+ if (StockCount == stockCount)
+ {
+ return this;
+ }
+
+ if (triggerEvent)
+ {
+ AddDistributedEvent(new ProductStockCountChangedEto(StockCount, stockCount));
+ }
+
+ StockCount = stockCount;
+ return this;
+ }
+ }
+}
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductCodeAlreadyExistsException.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductCodeAlreadyExistsException.cs
new file mode 100644
index 0000000000..1a15a5005d
--- /dev/null
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductCodeAlreadyExistsException.cs
@@ -0,0 +1,13 @@
+using Volo.Abp;
+
+namespace ProductManagement
+{
+ public class ProductCodeAlreadyExistsException : BusinessException
+ {
+ public ProductCodeAlreadyExistsException(string productCode)
+ : base("PM:000001", $"A product with code {productCode} has already exists!")
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/ProductManagementConsts.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductManagementConsts.cs
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/ProductManagementConsts.cs
rename to samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductManagementConsts.cs
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/ProductManagementDomainModule.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductManagementDomainModule.cs
similarity index 74%
rename from samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/ProductManagementDomainModule.cs
rename to samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductManagementDomainModule.cs
index 5f7d0009fc..8d20b094ef 100644
--- a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/MyCompanyName/ProductManagement/ProductManagementDomainModule.cs
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductManagementDomainModule.cs
@@ -1,5 +1,5 @@
-using Microsoft.Extensions.DependencyInjection;
-using ProductManagement.Localization;
+using ProductManagement.Localization;
+using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
@@ -7,8 +7,12 @@ using Volo.Abp.VirtualFileSystem;
namespace ProductManagement
{
+ /* This module directly depends on EF Core by its design.
+ * In this way, we can directly use EF Core async LINQ extension methods.
+ */
[DependsOn(
- typeof(ProductManagementDomainSharedModule)
+ typeof(ProductManagementDomainSharedModule),
+ typeof(AbpEntityFrameworkCoreModule)
)]
public class ProductManagementDomainModule : AbpModule
{
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductManager.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductManager.cs
new file mode 100644
index 0000000000..4c39feb7bf
--- /dev/null
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductManager.cs
@@ -0,0 +1,42 @@
+using JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Domain.Services;
+
+namespace ProductManagement
+{
+ public class ProductManager : DomainService
+ {
+ private readonly IRepository _productRepository;
+
+ public ProductManager(IRepository productRepository)
+ {
+ _productRepository = productRepository;
+ }
+
+ public async Task CreateAsync(
+ [NotNull] string code,
+ [NotNull] string name,
+ float price = 0.0f,
+ int stockCount = 0)
+ {
+ var existingProduct = await _productRepository.FirstOrDefaultAsync(p => p.Code == code);
+ if (existingProduct != null)
+ {
+ throw new ProductCodeAlreadyExistsException(code);
+ }
+
+ return await _productRepository.InsertAsync(
+ new Product(
+ GuidGenerator.Create(),
+ code,
+ name,
+ price,
+ stockCount
+ )
+ );
+ }
+ }
+}
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductStockCountChangedEto.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductStockCountChangedEto.cs
new file mode 100644
index 0000000000..c456a7c135
--- /dev/null
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/ProductStockCountChangedEto.cs
@@ -0,0 +1,24 @@
+using System;
+using Volo.Abp.Domain.Entities.Events.Distributed;
+
+namespace ProductManagement
+{
+ [Serializable]
+ public class ProductStockCountChangedEto : EtoBase
+ {
+ public int OldCount { get; set; }
+
+ public int CurrentCount { get; set; }
+
+ private ProductStockCountChangedEto()
+ {
+ //Default constructor is needed for deserialization.
+ }
+
+ public ProductStockCountChangedEto(int oldCount, int currentCount)
+ {
+ OldCount = oldCount;
+ CurrentCount = currentCount;
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementDbContextModelCreatingExtensions.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementDbContextModelCreatingExtensions.cs
deleted file mode 100644
index a370b228c9..0000000000
--- a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementDbContextModelCreatingExtensions.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using Microsoft.EntityFrameworkCore;
-using Volo.Abp;
-
-namespace ProductManagement.EntityFrameworkCore
-{
- public static class ProductManagementDbContextModelCreatingExtensions
- {
- public static void ConfigureProductManagement(
- this ModelBuilder builder,
- Action optionsAction = null)
- {
- Check.NotNull(builder, nameof(builder));
-
- var options = new ProductManagementModelBuilderConfigurationOptions();
-
- optionsAction?.Invoke(options);
-
- /* Configure all entities here. Example:
-
- builder.Entity(b =>
- {
- //Configure table & schema name
- //b.ToTable(options.TablePrefix + "Questions", options.Schema);
-
- //Properties
- //b.Property(q => q.Title).IsRequired().HasMaxLength(QuestionConsts.MaxTitleLength);
-
- //Configure relations
- //b.HasMany(question => question.Tags).WithOne().HasForeignKey(qt => qt.QuestionId);
-
- //Configure indexes
- //b.HasIndex(q => q.CreationTime);
- });
- */
- }
- }
-}
\ No newline at end of file
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/IProductManagementDbContext.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/IProductManagementDbContext.cs
similarity index 60%
rename from samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/IProductManagementDbContext.cs
rename to samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/IProductManagementDbContext.cs
index f0de764e00..be1950d69f 100644
--- a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/IProductManagementDbContext.cs
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/IProductManagementDbContext.cs
@@ -1,4 +1,5 @@
-using Volo.Abp.Data;
+using Microsoft.EntityFrameworkCore;
+using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
namespace ProductManagement.EntityFrameworkCore
@@ -6,8 +7,6 @@ namespace ProductManagement.EntityFrameworkCore
[ConnectionStringName("ProductManagement")]
public interface IProductManagementDbContext : IEfCoreDbContext
{
- /* Add DbSet for each Aggregate Root here. Example:
- * DbSet Questions { get; }
- */
+ DbSet Products { get; }
}
}
\ No newline at end of file
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementDbContext.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementDbContext.cs
similarity index 88%
rename from samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementDbContext.cs
rename to samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementDbContext.cs
index ba5fd5c1b8..03a3d52394 100644
--- a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementDbContext.cs
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementDbContext.cs
@@ -11,9 +11,7 @@ namespace ProductManagement.EntityFrameworkCore
public static string Schema { get; set; } = ProductManagementConsts.DefaultDbSchema;
- /* Add DbSet for each Aggregate Root here. Example:
- * public DbSet Questions { get; set; }
- */
+ public DbSet Products { get; set; }
public ProductManagementDbContext(DbContextOptions options)
: base(options)
@@ -31,5 +29,6 @@ namespace ProductManagement.EntityFrameworkCore
options.Schema = Schema;
});
}
+
}
}
\ No newline at end of file
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementDbContextModelCreatingExtensions.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementDbContextModelCreatingExtensions.cs
new file mode 100644
index 0000000000..2adf0c4f71
--- /dev/null
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementDbContextModelCreatingExtensions.cs
@@ -0,0 +1,34 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Volo.Abp;
+using Volo.Abp.EntityFrameworkCore.Modeling;
+
+namespace ProductManagement.EntityFrameworkCore
+{
+ public static class ProductManagementDbContextModelCreatingExtensions
+ {
+ public static void ConfigureProductManagement(
+ this ModelBuilder builder,
+ Action optionsAction = null)
+ {
+ Check.NotNull(builder, nameof(builder));
+
+ var options = new ProductManagementModelBuilderConfigurationOptions();
+
+ optionsAction?.Invoke(options);
+
+ builder.Entity(b =>
+ {
+ b.ToTable(options.TablePrefix + "Products", options.Schema);
+
+ b.ConfigureAudited();
+
+ b.Property(x => x.Code).IsRequired().HasMaxLength(ProductConsts.MaxCodeLength);
+ b.Property(x => x.Name).IsRequired().HasMaxLength(ProductConsts.MaxNameLength);
+
+ b.HasIndex(q => q.Code);
+ b.HasIndex(q => q.Name);
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreModule.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreModule.cs
similarity index 78%
rename from samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreModule.cs
rename to samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreModule.cs
index d6bdfb7b26..04d155ee9b 100644
--- a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreModule.cs
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreModule.cs
@@ -14,9 +14,7 @@ namespace ProductManagement.EntityFrameworkCore
{
context.Services.AddAbpDbContext(options =>
{
- /* Add custom repositories here. Example:
- * options.AddRepository();
- */
+ options.AddDefaultRepositories();
});
}
}
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementModelBuilderConfigurationOptions.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementModelBuilderConfigurationOptions.cs
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementModelBuilderConfigurationOptions.cs
rename to samples/MicroserviceDemo/modules/product/src/ProductManagement.EntityFrameworkCore/ProductManagement/EntityFrameworkCore/ProductManagementModelBuilderConfigurationOptions.cs
diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/ProductManagement.Web.csproj b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/ProductManagement.Web.csproj
index 135271bfc6..578fff59a8 100644
--- a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/ProductManagement.Web.csproj
+++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/ProductManagement.Web.csproj
@@ -9,15 +9,17 @@
-
-
+
+
+
+
@@ -28,8 +30,4 @@
-
-
-
-
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.Application.Tests/MyCompanyName/ProductManagement/ProductManagementApplicationTestModule.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.Application.Tests/ProductManagement/ProductManagementApplicationTestModule.cs
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/test/ProductManagement.Application.Tests/MyCompanyName/ProductManagement/ProductManagementApplicationTestModule.cs
rename to samples/MicroserviceDemo/modules/product/test/ProductManagement.Application.Tests/ProductManagement/ProductManagementApplicationTestModule.cs
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/MyCompanyName/ProductManagement/ProductManagementDomainTestBase.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/MyCompanyName/ProductManagement/ProductManagementDomainTestBase.cs
deleted file mode 100644
index 517bc71e6b..0000000000
--- a/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/MyCompanyName/ProductManagement/ProductManagementDomainTestBase.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ProductManagement
-{
- public abstract class ProductManagementDomainTestBase : ProductManagementTestBase
- {
-
- }
-}
\ No newline at end of file
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/ProductManagement/ProductManagementDomainTestBase.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/ProductManagement/ProductManagementDomainTestBase.cs
new file mode 100644
index 0000000000..7ad63742ba
--- /dev/null
+++ b/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/ProductManagement/ProductManagementDomainTestBase.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Uow;
+
+namespace ProductManagement
+{
+ public abstract class ProductManagementDomainTestBase : ProductManagementTestBase
+ {
+ #region WithUnitOfWork
+
+ protected virtual void WithUnitOfWork(Action action)
+ {
+ WithUnitOfWork(new UnitOfWorkOptions(), action);
+ }
+
+ protected virtual void WithUnitOfWork(UnitOfWorkOptions options, Action action)
+ {
+ using (var scope = ServiceProvider.CreateScope())
+ {
+ var uowManager = scope.ServiceProvider.GetRequiredService();
+
+ using (var uow = uowManager.Begin(options))
+ {
+ action();
+
+ uow.Complete();
+ }
+ }
+ }
+
+ protected virtual Task WithUnitOfWorkAsync(Func func)
+ {
+ return WithUnitOfWorkAsync(new UnitOfWorkOptions(), func);
+ }
+
+ protected virtual async Task WithUnitOfWorkAsync(UnitOfWorkOptions options, Func action)
+ {
+ using (var scope = ServiceProvider.CreateScope())
+ {
+ var uowManager = scope.ServiceProvider.GetRequiredService();
+
+ using (var uow = uowManager.Begin(options))
+ {
+ await action();
+
+ await uow.CompleteAsync();
+ }
+ }
+ }
+
+ protected virtual TResult WithUnitOfWork(Func func)
+ {
+ return WithUnitOfWork(new UnitOfWorkOptions(), func);
+ }
+
+ protected virtual TResult WithUnitOfWork(UnitOfWorkOptions options, Func func)
+ {
+ using (var scope = ServiceProvider.CreateScope())
+ {
+ var uowManager = scope.ServiceProvider.GetRequiredService();
+
+ using (var uow = uowManager.Begin(options))
+ {
+ var result = func();
+ uow.Complete();
+ return result;
+ }
+ }
+ }
+
+ protected virtual Task WithUnitOfWorkAsync(Func> func)
+ {
+ return WithUnitOfWorkAsync(new UnitOfWorkOptions(), func);
+ }
+
+ protected virtual async Task WithUnitOfWorkAsync(UnitOfWorkOptions options, Func> func)
+ {
+ using (var scope = ServiceProvider.CreateScope())
+ {
+ var uowManager = scope.ServiceProvider.GetRequiredService();
+
+ using (var uow = uowManager.Begin(options))
+ {
+ var result = await func();
+ await uow.CompleteAsync();
+ return result;
+ }
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/MyCompanyName/ProductManagement/ProductManagementDomainTestModule.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/ProductManagement/ProductManagementDomainTestModule.cs
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/MyCompanyName/ProductManagement/ProductManagementDomainTestModule.cs
rename to samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/ProductManagement/ProductManagementDomainTestModule.cs
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/ProductManagement/ProductManager_Tests.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/ProductManagement/ProductManager_Tests.cs
new file mode 100644
index 0000000000..974beba3c3
--- /dev/null
+++ b/samples/MicroserviceDemo/modules/product/test/ProductManagement.Domain.Tests/ProductManagement/ProductManager_Tests.cs
@@ -0,0 +1,34 @@
+using System.Threading.Tasks;
+using Shouldly;
+using Xunit;
+
+namespace ProductManagement
+{
+ public class ProductManager_Tests : ProductManagementDomainTestBase
+ {
+ private readonly ProductManager _productManager;
+
+ public ProductManager_Tests()
+ {
+ _productManager = GetRequiredService();
+ }
+
+ [Fact]
+ public async Task Should_Create_A_Valid_Product()
+ {
+ //Act
+ var product = await WithUnitOfWorkAsync(
+ async () =>
+ {
+ return await _productManager.CreateAsync("P000837212", "My Product 837212", stockCount: 42);
+ }
+ );
+
+ //Assert
+ product.Code.ShouldBe("P000837212");
+ product.Name.ShouldBe("My Product 837212");
+ product.Price.ShouldBe(0.0f);
+ product.StockCount.ShouldBe(42);
+ }
+ }
+}
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.EntityFrameworkCore.Tests/MyCompanyName/ProductManagement/EntityFrameworkCore/MyEntityRepository_Tests.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.EntityFrameworkCore.Tests/MyCompanyName/ProductManagement/EntityFrameworkCore/MyEntityRepository_Tests.cs
deleted file mode 100644
index 11195d30a0..0000000000
--- a/samples/MicroserviceDemo/modules/product/test/ProductManagement.EntityFrameworkCore.Tests/MyCompanyName/ProductManagement/EntityFrameworkCore/MyEntityRepository_Tests.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ProductManagement.EntityFrameworkCore
-{
- public class MyEntityRepository_Tests : MyEntityRepository_Tests
- {
-
- }
-}
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.EntityFrameworkCore.Tests/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreTestModule.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.EntityFrameworkCore.Tests/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreTestModule.cs
similarity index 96%
rename from samples/MicroserviceDemo/modules/product/test/ProductManagement.EntityFrameworkCore.Tests/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreTestModule.cs
rename to samples/MicroserviceDemo/modules/product/test/ProductManagement.EntityFrameworkCore.Tests/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreTestModule.cs
index cb98e6de9d..0af5c49ba9 100644
--- a/samples/MicroserviceDemo/modules/product/test/ProductManagement.EntityFrameworkCore.Tests/MyCompanyName/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreTestModule.cs
+++ b/samples/MicroserviceDemo/modules/product/test/ProductManagement.EntityFrameworkCore.Tests/ProductManagement/EntityFrameworkCore/ProductManagementEntityFrameworkCoreTestModule.cs
@@ -2,7 +2,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
-using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/MyEntityRepository_Tests.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/MyEntityRepository_Tests.cs
deleted file mode 100644
index a985263bf6..0000000000
--- a/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/MyEntityRepository_Tests.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Threading.Tasks;
-using Volo.Abp.Modularity;
-using Xunit;
-
-namespace ProductManagement
-{
- public abstract class MyEntityRepository_Tests : ProductManagementTestBase
- where TStartupModule : IAbpModule
- {
- [Fact]
- public async Task Test1()
- {
-
- }
- }
-}
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/ProductManagementTestBase.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/ProductManagement/ProductManagementTestBase.cs
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/ProductManagementTestBase.cs
rename to samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/ProductManagement/ProductManagementTestBase.cs
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/ProductManagementTestBaseModule.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/ProductManagement/ProductManagementTestBaseModule.cs
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/ProductManagementTestBaseModule.cs
rename to samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/ProductManagement/ProductManagementTestBaseModule.cs
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/ProductManagementTestData.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/ProductManagement/ProductManagementTestData.cs
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/ProductManagementTestData.cs
rename to samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/ProductManagement/ProductManagementTestData.cs
diff --git a/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/ProductManagementTestDataBuilder.cs b/samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/ProductManagement/ProductManagementTestDataBuilder.cs
similarity index 100%
rename from samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/MyCompanyName/ProductManagement/ProductManagementTestDataBuilder.cs
rename to samples/MicroserviceDemo/modules/product/test/ProductManagement.TestBase/ProductManagement/ProductManagementTestDataBuilder.cs