aspnetboilerplate / aspnetboilerplate

ASP.NET Boilerplate - Web Application Framework
https://aspnetboilerplate.com
MIT License
11.84k stars 3.79k forks source link

Issue: Found more than one concrete type for given DbContext Type After Upgrading to Abp 0.9.3 #1097

Closed iyhammad closed 8 years ago

iyhammad commented 8 years ago

Hi,

Background

I've a multi module system and every module has itsown DbContext. All the modules' DbContext inherits the base module DbContext which in turns inherits the AboZeroDbContext.

The Issue

After upgrading to Abp 0.9.3 I got the below exception everywhere in the system.

Found more than one concrete type for given DbContext Type (HRPayroll.Data.HrPayrollDbContext) but none of them defines MultiTenancySideAttribute with Host. Found types: .

Stack trace:

[AbpException: Found more than one concrete type for given DbContext Type (DreamApp.Data.DreamAppDbContext) but none of them defines MultiTenancySideAttribute with Host. Found types: .]
   Abp.EntityFramework.DbContextTypeMatcher.GetConcreteType(Type sourceDbContextType) in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\DbContextTypeMatcher.cs:129
   Abp.EntityFramework.Uow.EfUnitOfWork.GetOrCreateDbContext(Nullable`1 multiTenancySide) in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Uow\EfUnitOfWork.cs:140
   Abp.EntityFramework.Repositories.EfRepositoryBase`3.get_Table() in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Repositories\EfRepositoryBaseOfTEntityAndTPrimaryKey.cs:30
   Abp.EntityFramework.Repositories.<GetAllListAsync>d__7.MoveNext() in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Repositories\EfRepositoryBaseOfTEntityAndTPrimaryKey.cs:50
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Abp.Threading.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__5`1.MoveNext() in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs:120
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Abp.Threading.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__5`1.MoveNext() in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs:120
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Abp.Localization.<GetLanguagesFromDatabaseAsync>d__17.MoveNext() in D:\Halil\GitHub\module-zero\src\Abp.Zero\Localization\ApplicationLanguageManager.cs:204
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Abp.Threading.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__5`1.MoveNext() in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs:120
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Abp.Runtime.Caching.<<GetAsync>b__0>d.MoveNext() in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Runtime\Caching\CacheExtensions.cs:0
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Abp.Runtime.Caching.<GetAsync>d__12.MoveNext() in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Runtime\Caching\CacheBase.cs:67
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Abp.Runtime.Caching.<GetAsync>d__5`2.MoveNext() in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Runtime\Caching\CacheExtensions.cs:38
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Abp.Localization.<GetLanguageDictionary>d__15.MoveNext() in D:\Halil\GitHub\module-zero\src\Abp.Zero\Localization\ApplicationLanguageManager.cs:178
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Abp.Localization.<GetLanguagesAsync>d__8.MoveNext() in D:\Halil\GitHub\module-zero\src\Abp.Zero\Localization\ApplicationLanguageManager.cs:60
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task`1 task) +48
   System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke() +108
   System.Threading.Tasks.Task.Execute() +71
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13891908
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task`1 task) +48
   Nito.AsyncEx.AsyncContext.Run(Func`1 action) +382
   Abp.Localization.ApplicationLanguageProvider.GetLanguages() in D:\Halil\GitHub\module-zero\src\Abp.Zero\Localization\ApplicationLanguageProvider.cs:35
   Abp.Localization.LanguageManager.GetCurrentLanguage() in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Localization\LanguageManager.cs:26
   DreamApp.Sessions.SessionAppService.SetCurrentUiCulture() in d:\src\DreamApp\src\DreamApp.Application\Sessions\SessionAppService.cs:36
   Castle.DynamicProxy.AbstractInvocation.Proceed() +111
   Castle.DynamicProxy.AbstractInvocation.Proceed() +448
   Abp.Domain.Uow.UnitOfWorkInterceptor.PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:54
   Castle.DynamicProxy.AbstractInvocation.Proceed() +448
   Castle.DynamicProxy.AbstractInvocation.Proceed() +448
   Castle.DynamicProxy.AbstractInvocation.Proceed() +448
   DreamApp.Web.Controllers.DreamAppControllerBase..ctor() in d:\src\DreamApp\src\DreamApp.Web\Controllers\DreamAppControllerBase.cs:19
   DreamApp.Web.Controllers.HomeController..ctor() +43

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
   System.Reflection.RuntimeConstructorInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +438
   Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.FastCreateInstance(Type implType, Object[] arguments, ConstructorCandidate constructor) +106
   Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstanceCore(ConstructorCandidate constructor, Object[] arguments, Type implType) +62

[ComponentActivatorException: ComponentActivator: could not instantiate DreamApp.Web.Controllers.HomeController]
   Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstanceCore(ConstructorCandidate constructor, Object[] arguments, Type implType) +335
   Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context, ConstructorCandidate constructor, Object[] arguments) +284
   Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) +29
   Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) +26
   Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally) +62
   Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) +28
   Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) +294
   Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) +33
   Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy) +170
   Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy) +73
   Abp.Dependency.IocManager.Resolve(Type type) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Dependency\IocManager.cs:171
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +103
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +268
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +95
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +923
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +137

Any thoughts ?

hikalkan commented 8 years ago

Hi,

Can you share your DbContext hierarchy? I'm working on this issue to understand it.

hikalkan commented 8 years ago

I suppose this will solve your problem: https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1119

hikalkan commented 8 years ago

I'm closing this issue. It will be released as v0.9.4. If it can not solve the problem, please re-open this issue. Thanks.

iyhammad commented 8 years ago

Hi, I've upgraded to ABP v0.9.4 and marked my MainDbContext as DefaultDbContext and this doesn't resolve my issue. In My System I've MainDbContext that inherits AbpZeroDbContext<Tenant, Role, User> and every module DbContext inherits MainDbContext. Also MainDbContext and every Module DbContext has AutoRepositoryTypes Thanks,

hikalkan commented 8 years ago

OK. We will solve the problem. But I need your help. First, can you share the stack trace and the exception message again. I improved the exception message, so we can see this "multiple dbcontext" list.

hikalkan commented 8 years ago

Is your MainDbContext abstract? DefaultDbContext attribute should be added to a non-abstract class. Try to add it to one of your modules (the most major/common module if one exists).

iyhammad commented 8 years ago

Hi Halil,

Thank you for your efforts towards resolving this issue.

You can find here a sample solution that demonstrate the issue https://github.com/iyhammad/AdventureWorks

to regenerate the issue Just do login using Postman.

My Stack Trace:

ERROR 2016-06-19 13:19:14,966 [7    ] eWorks.Web.Controllers.AccountController - Found more than one concrete type for given DbContext Type (AdventureWorks.EntityFramework.AdventureWorksDbContext) define MultiTenancySideAttribute with Tenant. Found types: AdventureWorks.EntityFramework.AdventureWorksDbContext, AdventureWorks.EntityFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null, AdventureWorks.Sales.EntityFramework.EntityFramework.SalesDbContext, AdventureWorks.Sales.EntityFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
Abp.AbpException: Found more than one concrete type for given DbContext Type (AdventureWorks.EntityFramework.AdventureWorksDbContext) define MultiTenancySideAttribute with Tenant. Found types: AdventureWorks.EntityFramework.AdventureWorksDbContext, AdventureWorks.EntityFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null, AdventureWorks.Sales.EntityFramework.EntityFramework.SalesDbContext, AdventureWorks.Sales.EntityFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
   at Abp.EntityFramework.DbContextTypeMatcher`1.GetDefaultDbContextType(List`1 dbContextTypes, Type sourceDbContextType, MultiTenancySides tenancySide) in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework.Common\DbContextTypeMatcher.cs:line 131
   at Abp.EntityFramework.DbContextTypeMatcher`1.GetConcreteType(Type sourceDbContextType) in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework.Common\DbContextTypeMatcher.cs:line 79
   at Abp.EntityFramework.Uow.EfUnitOfWork.GetOrCreateDbContext[TDbContext](Nullable`1 multiTenancySide) in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Uow\EfUnitOfWork.cs:line 140
   at Abp.EntityFramework.Uow.UnitOfWorkExtensions.GetDbContext[TDbContext](IActiveUnitOfWork unitOfWork, Nullable`1 multiTenancySide) in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Uow\UnitOfWorkExtensions.cs:line 38
   at Abp.EntityFramework.Uow.UnitOfWorkDbContextProvider`1.GetDbContext(Nullable`1 multiTenancySide) in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Uow\UnitOfWorkDbContextProvider.cs:line 38
   at Abp.EntityFramework.Repositories.EfRepositoryBase`3.get_Context() in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Repositories\EfRepositoryBaseOfTEntityAndTPrimaryKey.cs:line 25
   at Abp.EntityFramework.Repositories.EfRepositoryBase`3.get_Table() in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Repositories\EfRepositoryBaseOfTEntityAndTPrimaryKey.cs:line 30
   at Abp.EntityFramework.Repositories.EfRepositoryBase`3.InsertAsync(TEntity entity) in D:\Halil\GitHub\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Repositories\EfRepositoryBaseOfTEntityAndTPrimaryKey.cs:line 80
   at Castle.Proxies.Invocations.IRepository`2_InsertAsync_14.InvokeMethodOnTarget()
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformAsyncUow(IInvocation invocation, UnitOfWorkOptions options) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 62
   at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformUow(IInvocation invocation, UnitOfWorkOptions options) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 41
   at Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 35
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformAsyncUow(IInvocation invocation, UnitOfWorkOptions options) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 62
   at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformUow(IInvocation invocation, UnitOfWorkOptions options) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 41
   at Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 35
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.IRepository`2Proxy_11.InsertAsync(AuditLog entity)
   at Abp.Auditing.AuditingStore.SaveAsync(AuditInfo auditInfo) in D:\Halil\GitHub\module-zero\src\Abp.Zero\Auditing\AuditingStore.cs:line 24
   at Abp.Auditing.AuditingStoreExtensions.<>c__DisplayClass0_0.<Save>b__0() in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Auditing\AuditingStoreExtensions.cs:line 17
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
   at Nito.AsyncEx.AsyncContext.<>c__DisplayClass3.<Run>b__1(Task t)
   at System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
   at Nito.AsyncEx.AsyncContext.Run(Func`1 action)
   at Abp.Threading.AsyncHelper.RunSync(Func`1 action) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Threading\AsyncHelper.cs:line 42
   at Abp.Auditing.AuditingStoreExtensions.Save(IAuditingStore auditingStore, AuditInfo auditInfo) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Auditing\AuditingStoreExtensions.cs:line 17
   at Abp.Web.Mvc.Controllers.AbpController.HandleAuditingAfterAction(ActionExecutedContext filterContext) in D:\Halil\GitHub\aspnetboilerplate\src\Abp.Web.Mvc\Web\Mvc\Controllers\AbpController.cs:line 466
   at Castle.Proxies.AccountControllerProxy.OnActionExecuted_callback(ActionExecutedContext filterContext)
   at Castle.Proxies.Invocations.AbpController_OnActionExecuted.InvokeMethodOnTarget()
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation) in D:\Halil\GitHub\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 29
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.AccountControllerProxy.OnActionExecuted(ActionExecutedContext filterContext)
   at System.Web.Mvc.Controller.System.Web.Mvc.IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)

My MainDbContext is not abstract. I tried to add the DefaultDbContext to any of the modules it didn't help. However by design the Default should be the Main for me I guess.

Thanks,

hikalkan commented 8 years ago

Thank you for sharing the code. I'm checking it.

hikalkan commented 8 years ago

Can you try this:

  1. Create a class derived from DbContextTypeMatcher like that:
public class MyDbContextTypeMatcher : DbContextTypeMatcher
{
    public MyDbContextTypeMatcher(ICurrentUnitOfWorkProvider currentUnitOfWorkProvider) 
        : base(currentUnitOfWorkProvider)
    {
    }

    public override Type GetConcreteType(Type sourceDbContextType)
    {
        if (!sourceDbContextType.IsAbstract)
        {
            return sourceDbContextType;
        }

        return base.GetConcreteType(sourceDbContextType);
    }
}

In PreInitialize method of your module, replace the service with your custom one:

Configuration.ReplaceService<IDbContextTypeMatcher, MyDbContextTypeMatcher>();

And see if this fixes the problem.

Note: You can write these code in your Web project or in any of your EF projects.

Thanks.

iyhammad commented 8 years ago

Thank you Halil, It resolved the issue. Is it a temporary solution?

hikalkan commented 8 years ago

No, this is the correct solution and will be included in the next release (so, you can remove your that code in the next release). Thank you for your support to test it.

iyhammad commented 8 years ago

You Welcome. I really enjoy working with ABP on daily basis.

hikalkan commented 8 years ago

OK, released v0.9.5. Just upgrade nuget packages and remove your custom code. Have a nice day.