diff --git a/docs/en/Tutorials/Angular/Part-I.md b/docs/en/Tutorials/Angular/Part-I.md index d48b76222a..fdc8de4bf4 100644 --- a/docs/en/Tutorials/Angular/Part-I.md +++ b/docs/en/Tutorials/Angular/Part-I.md @@ -19,7 +19,7 @@ Create a new project named `Acme.BookStore` by selecting the Angular as the UI f This is how the layered solution structure looks after it's created: -![bookstore-backend-solution](images/bookstore-backend-solution.png) +![bookstore-backend-solution](images\bookstore-backend-solution-v2.png) > You can see the [Application template document](../../Startup-Templates/Application.md) to understand the solution structure in details. However, you will understand the basics with this tutorial. @@ -79,10 +79,73 @@ namespace Acme.BookStore #### Add Book Entity to Your DbContext -... +Add a `IMongoCollection` property to the `BookStoreMongoDbContext` inside the `Acme.BookStore.MongoDB` project: + +````csharp +public class BookStoreMongoDbContext : AbpMongoDbContext +{ + public IMongoCollection Books => Collection(); + ... +} +```` #### Add Seed (Sample) Data +This section is optional, but it would be good to have an initial data in the database in the first run. ABP provides a [data seed system](../../Data-Seeding.md). Create a class deriving from the `IDataSeedContributor` in the `.Domain` project: + +````csharp +using System; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; + +namespace Acme.BookStore +{ + public class BookStoreDataSeederContributor + : IDataSeedContributor, ITransientDependency + { + private readonly IRepository _bookRepository; + + public BookStoreDataSeederContributor(IRepository bookRepository) + { + _bookRepository = bookRepository; + } + + public async Task SeedAsync(DataSeedContext context) + { + if (await _bookRepository.GetCountAsync() > 0) + { + return; + } + + await _bookRepository.InsertAsync( + new Book + { + Name = "1984", + Type = BookType.Dystopia, + PublishDate = new DateTime(1949, 6, 8), + Price = 19.84f + } + ); + + await _bookRepository.InsertAsync( + new Book + { + Name = "The Hitchhiker's Guide to the Galaxy", + Type = BookType.ScienceFiction, + PublishDate = new DateTime(1995, 9, 27), + Price = 42.0f + } + ); + } + } +} + +```` + +`BookStoreDataSeederContributor` simply inserts two books into database if there is no book added before. ABP automatically discovers and executes this class when you seed the database by running the `Acme.BookStore.DbMigrator` project. + ### Create the Application Service The next step is to create an [application service](../../Application-Services.md) to manage (create, list, update, delete...) the books. Application layer in the startup template is separated into two projects: diff --git a/docs/en/Tutorials/Angular/images/bookstore-backend-solution-v2.png b/docs/en/Tutorials/Angular/images/bookstore-backend-solution-v2.png new file mode 100644 index 0000000000..79bcecb561 Binary files /dev/null and b/docs/en/Tutorials/Angular/images/bookstore-backend-solution-v2.png differ diff --git a/docs/en/Tutorials/Angular/images/bookstore-backend-solution.png b/docs/en/Tutorials/Angular/images/bookstore-backend-solution.png deleted file mode 100644 index 4264af5f80..0000000000 Binary files a/docs/en/Tutorials/Angular/images/bookstore-backend-solution.png and /dev/null differ diff --git a/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain.Shared/BookType.cs b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain.Shared/BookType.cs new file mode 100644 index 0000000000..ba84b4fe2a --- /dev/null +++ b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain.Shared/BookType.cs @@ -0,0 +1,15 @@ +namespace Acme.BookStore +{ + public enum BookType + { + Undefined, + Adventure, + Biography, + Dystopia, + Fantastic, + Horror, + Science, + ScienceFiction, + Poetry + } +} \ No newline at end of file diff --git a/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/Book.cs b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/Book.cs new file mode 100644 index 0000000000..93dd6d9adc --- /dev/null +++ b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/Book.cs @@ -0,0 +1,16 @@ +using System; +using Volo.Abp.Domain.Entities.Auditing; + +namespace Acme.BookStore +{ + public class Book : AuditedAggregateRoot + { + public string Name { get; set; } + + public BookType Type { get; set; } + + public DateTime PublishDate { get; set; } + + public float Price { get; set; } + } +} \ No newline at end of file diff --git a/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/BookStoreDataSeederContributor.cs b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/BookStoreDataSeederContributor.cs new file mode 100644 index 0000000000..479bac36e2 --- /dev/null +++ b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.Domain/BookStoreDataSeederContributor.cs @@ -0,0 +1,46 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; + +namespace Acme.BookStore +{ + public class BookStoreDataSeederContributor : IDataSeedContributor, ITransientDependency + { + private readonly IRepository _bookRepository; + + public BookStoreDataSeederContributor(IRepository bookRepository) + { + _bookRepository = bookRepository; + } + + public async Task SeedAsync(DataSeedContext context) + { + if (await _bookRepository.GetCountAsync() > 0) + { + return; + } + + await _bookRepository.InsertAsync( + new Book + { + Name = "1984", + Type = BookType.Dystopia, + PublishDate = new DateTime(1949, 6, 8), + Price = 19.84f + } + ); + + await _bookRepository.InsertAsync( + new Book + { + Name = "The Hitchhiker's Guide to the Galaxy", + Type = BookType.ScienceFiction, + PublishDate = new DateTime(1995, 9, 27), + Price = 42.0f + } + ); + } + } +} diff --git a/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.HttpApi.Host/appsettings.json b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.HttpApi.Host/appsettings.json index b5aba1d2b4..143c972ee1 100644 --- a/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.HttpApi.Host/appsettings.json +++ b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.HttpApi.Host/appsettings.json @@ -4,7 +4,7 @@ "CorsOrigins": "https://*.BookStore.com,http://localhost:4200" }, "ConnectionStrings": { - "Default": "Server=localhost;Database=BookStore;Trusted_Connection=True;MultipleActiveResultSets=true" + "Default": "mongodb://localhost:27017|BookStore" }, "Redis": { "Configuration": "127.0.0.1" diff --git a/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs index aca564be4c..5a28248c53 100644 --- a/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs +++ b/samples/BookStore-Angular-MongoDb/aspnet-core/src/Acme.BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs @@ -8,6 +8,8 @@ namespace Acme.BookStore.MongoDB [ConnectionStringName("Default")] public class BookStoreMongoDbContext : AbpMongoDbContext { + public IMongoCollection Books => Collection(); + public IMongoCollection Users => Collection(); protected override void CreateModel(IMongoModelBuilder modelBuilder)