Is there an example plugin that includes adding a new data context and services?
I can get services to work if the data context is not in the plugin, but i would like the data context to be int eh plugin as well.
4 Answer(s)
-
0
Hi @mittera
Unfortunately we don't have such a sample. Do you want a totally separate DbContext which belongs to PlugIn project ?
-
0
Yes i want to have a plugin that provides a service that uses a separate (existing) database to store it's information.
I can for see multiple plugins like this for my application and want it to be a plugin where the base connection string resolver doesn't need to know about it.
I can get it working if i add a reference and add the context to the connection string resolver...
But that is the apart i am trying to avoid by using a plugin.
How can i have a plugin with a separate database context?
I currently have three DB contexts in my application.
-
ABP Base Tables = AppDBContext
-
Host Tables = HostDbContext
-
Tenant Tables = TenantDbContext
-- New Plugin Context
4) Plugin Tables = MetadataDbContextUsing the code below works, but want the plugin code in the plugin...
When commenting out the metadata context from the connection string resolver it fails as the connection string is not initialized.
I am manually registering my context in the plugin, and at that time I am setting the connection string.
But when the app service code hits the context there is no connection string...
I feel i am close, but something is missing, any help would be appreciated!
public override string GetNameOrConnectionString(ConnectionStringResolveArgs args) { if (args.ContainsKey("ConnectionString")) { return args["ConnectionString"].ToString(); } if (args.ContainsKey("DbContextConcreteType")) { #region Host Database if (args["DbContextConcreteType"] as Type == typeof(HostDbContext) || args["DbContextConcreteType"] as Type == typeof(BaseAppDbContext)) { return base.GetNameOrConnectionString(args); } #endregion #region Metadata Database if (args["DbContextConcreteType"] as Type == typeof(MetadataDbContext)) { return System.Configuration.ConfigurationManager.ConnectionStrings["Metadata"].ConnectionString; } #endregion } #region Tenant Database int? tenantId = _currentUnitOfWorkProvider.Current.GetTenantId(); if (tenantId != null) { var tenantCacheItem = _tenantCache.Get(tenantId.Value); if (tenantCacheItem.ConnectionString.IsNullOrEmpty()) { return _appConfiguration[$"ConnectionStrings:Default"]; } return tenantCacheItem.ConnectionString; } #endregion #region Default Database return base.GetNameOrConnectionString(args); #endregion }
-
-
0
In the end it was a problem with the DbContext registration.
In addtion to setting the connection string like the host and tenant database, i also had to register the component afterwards in my preinitalize
Configuration.Modules.AbpEfCore().AddDbContext<MyDbContext>(options => { if (options.ExistingConnection != null) { MyDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection); } else { MyDbContextConfigurer.Configure(options.DbContextOptions, GetMyDbContextConnectionString()); } }); // Add this here to fix it. IocManager.IocContainer.Register( Castle.MicroKernel.Registration.Component.For<MyDbContext>() .UsingFactoryMethod(() => { var options = new DbContextOptionsBuilder<MyDbContext>() .UseSqlServer(GetMyDbContextConnectionString()) .Options; return new MyDbContext(options); }) .LifestyleTransient() );
-
0
Hi @mittera
Thank you for sharing the solution :)