How use Bounded Context Pattern in AspnetBoilerplate

201 Views Asked by At

How use Bounded Context Pattern in AspnetBoilerplate, Is there any way to use to use Bounded Context Pattern in AspnetBoilerplate?

2

There are 2 best solutions below

0
On

With EF you need one complete dbcontext for migrations.

Create other "bounded" dbcontext, with the entities to be ignored in modelbuilder, then use this in appservice.

Very simple answer HTH

0
On

Connect with multiple database in ASP.NET ZERO/ASP.NET BOILERPLATE.

Note - Use seperate DB Context to use multiple Databases.

Step 1. Create modal class in "MultipleDbContextEfCoreDemo.Core" Project for your tables.

[Table ("tblStudent")] //Is in First Database
public class Student : Entity<long> {
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    protected Student () { }
}

[Table ("tblCourses")] //Is in Second Database
public class Courses : Entity<long> {
    public int ID { get; set; }
    public string CourseName { get; set; }
    public string Standard { get; set; }

    protected Courses () { }
}

Step 2. In same project("MultipleDbContextEfCoreDemo.Core" Project) create/use "MultipleDbContextEfCoreDemoConsts.cs" file to add Database Connection names.

public class MultipleDbContextEfCoreDemoConsts
    {
        public const string LocalizationSourceName = "MultipleDbContextEfCoreDemo";

        public const string ConnectionStringName = "Default";

        public const string SecondDbConnectionStringName = "Second";
    }

Step 3. In "MultipleDbContextEfCoreDemo.EntityFrameworkCore" Project goto "EntityFrameworkCore" Folder and create individual "DBContext" and "DbContextConfigurer" file for each database connection to which you want to connect.

FirstDatabase Setting -

required files to connect to first db -

1. FirstDbContext.cs

public class FirstDbContext : AbpDbContext, IAbpPersistedGrantDbContext {
    /* Define an IDbSet for each entity of the application */
    public DbSet<PersistedGrantEntity> PersistedGrants { get; set; }
    public virtual DbSet<Student> Student { get; set; }

    public FirstDbContext (DbContextOptions<FirstDbContext> options) : base (options) {

    }

    protected override void OnModelCreating (ModelBuilder modelBuilder) { }
}

2. FirstDbContextConfigurer

public static class FirstDbContextConfigurer {
    public static void Configure (DbContextOptionsBuilder<FirstDbContext> builder, string connectionString) {
        builder.UseSqlServer (connectionString);
    }

    public static void Configure (DbContextOptionsBuilder<FirstDbContext> builder, DbConnection connection) {
        builder.UseSqlServer (connection);
    }
}

SecondDatabase Setting -

required files to connect to second db -

1. SecondDbContext.cs

public class SecondDbContext : AbpDbContext, IAbpPersistedGrantDbContext {
    /* Define an IDbSet for each entity of the application */
    public DbSet<PersistedGrantEntity> PersistedGrants { get; set; }
    public virtual DbSet<Student> Student { get; set; }

    public SecondDbContext (DbContextOptions<SecondDbContext> options) : base (options) {

    }

    protected override void OnModelCreating (ModelBuilder modelBuilder) { }
}

2. SecondDbContextConfigurer

public static class SecondDbContextConfigurer {
    public static void Configure (DbContextOptionsBuilder<SecondDbContext> builder, string connectionString) {
        builder.UseSqlServer (connectionString);
    }
    public static void Configure (DbContextOptionsBuilder<SecondDbContext> builder, DbConnection connection) {
        builder.UseSqlServer (connection);
    }
}

Step 4. Then in same project("MultipleDbContextEfCoreDemo.EntityFrameworkCore") add "MyConnectionStringResolver.cs"

public class MyConnectionStringResolver : DefaultConnectionStringResolver
        {
            public MyConnectionStringResolver(IAbpStartupConfiguration configuration) 
                : base(configuration)
            {
            }

            public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
            {
                if (args["DbContextConcreteType"] as Type == typeof(SecondDbContext))
                {
                    var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
                    return configuration.GetConnectionString(MultipleDbContextEfCoreDemoConsts.SecondDbConnectionStringName);
                }

                return base.GetNameOrConnectionString(args);
            }
        }

Step 5. Then in same project("MultipleDbContextEfCoreDemo.EntityFrameworkCore"), Update "MultipleDbContextEfCoreDemoEntityFrameworkCoreModule.cs" file to replace the "IConnectionStringResolver" with our custom implementation MyConnectionStringResolver.

[DependsOn(typeof(MultipleDbContextEfCoreDemoCoreModule), typeof(AbpEntityFrameworkCoreModule))]
    public class MultipleDbContextEfCoreDemoEntityFrameworkCoreModule : AbpModule
    {
        public override void PreInitialize()
        {
            Configuration.ReplaceService<IConnectionStringResolver, MyConnectionStringResolver>();

            // Configure first DbContext
            Configuration.Modules.AbpEfCore().AddDbContext<FirstDbContext>(options =>
            {
                if (options.ExistingConnection != null)
                {
                    FirstDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
                }
                else
                {
                    FirstDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
                }
            });

            // Configure second DbContext
            Configuration.Modules.AbpEfCore().AddDbContext<SecondDbContext>(options =>
            {
                if (options.ExistingConnection != null)
                {
                    SecondDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
                }
                else
                {
                    SecondDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
                }
            });
        }

        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(typeof(MultipleDbContextEfCoreDemoEntityFrameworkCoreModule).GetAssembly());
        }
    }

Step 6. Create the Service in "MultipleDbContextEfCoreDemo.Application" project with Dto, Interface and Service Class.

ITestAppService.cs-

public interface ITestAppService : IApplicationService
    {
        List<string> GetStudentAndCourses();

     }

TestAppService.cs

public class TestAppService : MultipleDbContextEfCoreDemoAppServiceBase, ITestAppService
    {
        private readonly IRepository<Student> _studentRepository; //in the first db
        private readonly IRepository<Courses> _coursesRepository; //in the second db

        public TestAppService(
            IRepository<Student> studentRepository,
            IRepository<Courses> coursesRepository
        )
        {
            _studentRepository = studentRepository;
            _coursesRepository = coursesRepository;
        }

        //a sample method uses both databases concurrently
        public List<string> GetStudentAndCourses()
        {
            List<string> names = new List<string>();

            var studentNames = _studentRepository.GetAllList().Select(p => "Student: " + p.FirstName).ToList();
            names.AddRange(peopleNames);

            var courseNames = _coursesRepository.GetAllList().Select(p => "Course: " + p.CourseName).ToList();
            names.AddRange(courseNames);

            return names;
        }
    }

Step 7. Add Database connectionStrings to your MultipleDbContextEfCoreDemo.Web/MultipleDbContextEfCoreDemo.Web.Host project's "appsettings.json" file.

{
  "ConnectionStrings": {
    "Default":
      "Server=XXX.XXX.XX.XX;Database=firstDB;Integrated Security=False;TrustServerCertificate=True;User ID=XX;Password=XXX;",
    "Second":
      "Server=XXX.XXX.XX.XX;Database=secondDB;Integrated Security=False;TrustServerCertificate=True;User ID=XX;Password=XXX;"
  }
  }

Step 8. Use Service in your angular/MVC project.