Base solution for your next web application

Activities of "mightyit"

One possible approach I have thought of, is to do the following:

  • Create an IFooTenantManager: IDomainService, ITransientDependency interface in my FooModule.Core.Shared submodule, and an implementation FooTenantManager: ITenantManager in FooModule.Core submodule.

I can then use constructor injection in BaseModule to inject IFooTenantManager, as it will resolve by convention to a concrete instance of FooTenantManager.

Would this be the best approach?

Hi

I've been developing a module (let's call this "FooModule") to integrate with my base solution (let's call this "BaseModule").

I am currently trying to figure out how to invoke ModuleFoo entity migrations from ModuleBase (my base solution) when a new Tenant is created.

I noticed that, in my generated base solution BaseModule, the generated TenantManager class invokes the DbMigrator class of the base solution to trigger database creation and migration for the tenant, whenever a new tenant is created. This functionality is located in BaseModule's core/domain layer project.

I also studied the example blog module solution to see how module migrations should be handled. I noticed a TenantManager class has been created inside the module's core/domain layer project. The example application that consumes the module, though, is a simple console application without any entities of it's own. As such it does not properly demonstrate how a module with entity migrations would be properly integrated into a base solution, with DDD-type layering, that has migrations of its own.

I am thus tryng to figure out:

  1. Is there a convention or structure at play here where each module should have it's own tenantManager class?
  2. If not, this would mean that I would have to call code from my Module's domain layer from the domain layer of my base solution to perform this function? This would create a circular dependency, since my module relies on multitenancy and identity interfaces in my base solution.

Thanks for the feedback - it helped me to resolve the problem.

I renamed my AbpZeroDbMigrator class to MySystemDbMigrator. After changing it back, the service now successfully resolves.

It seems there is a hard-coded dependency on this class name to resolve the IAbpZeroDbMigrator service, correct? I would like to suggest that for issue resolution it would be most helpful if all DI and naming conventions / hard-coded project dependencies were documented in a single place.

Please help.  I'm getting the following error on PostInitialize of my WebMVC module application. Please advise - I have reviewed module dependencies and I am not sure what the DI system is looking for here / what convention I have broken:

Castle.MicroKernel.Handlers.HandlerException HResult=0x80131500 Message=Can't create component 'Abp.MultiTenancy.AbpTenantManager'2[[MyCompany.MySystem.MultiTenancy.Tenant, MyCompany.MySystem.Core, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[MyCompany.MySystem.Authorization.Users.User, MyCompany.MySystem.Core, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]_9d905d3e-a891-4b74-a909-026b8044ccf5' **as it has dependencies to be satisfied.

'Abp.MultiTenancy.AbpTenantManager**'2[[MyCompany.MySystem.MultiTenancy.Tenant, MyCompany.MySystem.Core, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[MyCompany.MySystem.Authorization.Users.User, MyCompany.MySystem.Core, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]_9d905d3e-a891-4b74-a909-026b8044ccf5' is waiting for the following dependencies:

  • Service 'Abp.MultiTenancy.IAbpZeroDbMigrator' which was not registered. Source=Castle.Windsor StackTrace: at Castle.MicroKernel.Handlers.DefaultHandler.AssertNotWaitingForDependency() at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy, Boolean ignoreParentContext) at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy, Boolean ignoreParentContext) at Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments) at Castle.Windsor.MsDependencyInjection.ScopedWindsorServiceProvider.GetServiceInternal(Type serviceType, Boolean isOptional) at Castle.MicroKernel.ComponentActivator.FactoryMethodActivator1.Instantiate(CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) at Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally) at Castle.Windsor.MsDependencyInjection.MsScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) at Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally) at Castle.MicroKernel.Lifestyle.SingletonLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy, Boolean ignoreParentContext) at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy, Boolean ignoreParentContext) at Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments) at Castle.Windsor.WindsorContainer.Resolve[T]() at MyCompany.MySystem.Web.Startup.MySystemWebMvcModule.PostInitialize() in D:\Projects\MySystem\src\MyCompany.MySystem.Web.Mvc\Startup\MySystemWebMvcModule.cs:line 69 at System.Collections.Generic.List1.ForEach(Action`1 action) at Abp.AbpBootstrapper.Initialize()

I am trying to understand the reasoning behind the module system, and under which circumstances it would be beneficial to implement it over other standard options such as class libraries and Nuget packages (that is not clear from the official documentation).

Specifically when contrasted to class libraries and Nuget packages, I am trying to understand it's distinct value proposition.

  1. Which distinct benefits do I gain when I create and implement an ABP module, as opposed to a class library or Nuget package?
  2. Under which circumstances would it beneficial to create an ABP module as opposed to a normal class library or Nuget package

In other words, why use the module system, rather than just creating a Nuget package?

Hi

Current module system is server side focused. For the client side, you can create a script/task to copy related view/script files. We have no such a code yet.

Is this still the case with version 4.1?

Showing 61 to 66 of 66 entries