Last active
June 11, 2016 20:48
-
-
Save hikalkan/e035271493fa9fbd7fa026d44c690aa9 to your computer and use it in GitHub Desktop.
DbContextTypeMatcher test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Abp.Collections.Extensions; | |
using Abp.Dependency; | |
using Abp.Domain.Uow; | |
using Abp.EntityFramework.Repositories; | |
using Abp.MultiTenancy; | |
namespace Abp.EntityFramework | |
{ | |
public class MyDbContextTypeMatcher : IDbContextTypeMatcher | |
{ | |
private readonly ICurrentUnitOfWorkProvider _currentUnitOfWorkProvider; | |
private readonly Dictionary<Type, List<Type>> _dbContextTypes; | |
public MyDbContextTypeMatcher(ICurrentUnitOfWorkProvider currentUnitOfWorkProvider) | |
{ | |
_currentUnitOfWorkProvider = currentUnitOfWorkProvider; | |
_dbContextTypes = new Dictionary<Type, List<Type>>(); | |
} | |
public virtual void Add(Type sourceDbContextType, Type targetDbContextType) | |
{ | |
if (!_dbContextTypes.ContainsKey(sourceDbContextType)) | |
{ | |
_dbContextTypes[sourceDbContextType] = new List<Type>(); | |
} | |
_dbContextTypes[sourceDbContextType].Add(targetDbContextType); | |
} | |
public virtual Type GetConcreteType(Type sourceDbContextType) | |
{ | |
//TODO: This can also get MultiTenancySide to filter dbcontexes | |
//TODO: Can be optimized by extracting/caching MultiTenancySideAttribute attributes for DbContexes. | |
//Get possible concrete types for given DbContext type | |
var allTargetTypes = _dbContextTypes.GetOrDefault(sourceDbContextType); | |
if (allTargetTypes.IsNullOrEmpty()) | |
{ | |
//Not found any target type, return the given type if it's not abstract | |
if (sourceDbContextType.IsAbstract) | |
{ | |
throw new AbpException("Could not find a concrete implementation of given DbContext type: " + sourceDbContextType.AssemblyQualifiedName); | |
} | |
return sourceDbContextType; | |
} | |
if (allTargetTypes.Count == 1) | |
{ | |
//Only one type does exists, return it | |
return allTargetTypes[0]; | |
} | |
//Will decide the target type with current UOW, so it should be in a UOW. | |
if (_currentUnitOfWorkProvider.Current == null) | |
{ | |
throw new AbpException("GetConcreteType method should be called in a UOW."); | |
} | |
var currentTenancySide = _currentUnitOfWorkProvider.Current.GetTenantId() == null | |
? MultiTenancySides.Host | |
: MultiTenancySides.Tenant; | |
var multiTenancySideContexes = allTargetTypes.Where(type => | |
{ | |
var attrs = type.GetCustomAttributes(typeof(MultiTenancySideAttribute), true); | |
if (attrs.IsNullOrEmpty()) | |
{ | |
return false; | |
} | |
return ((MultiTenancySideAttribute)attrs[0]).Side.HasFlag(currentTenancySide); | |
}).ToList(); | |
//Try to get the DbContext which is for current multitenancy side. | |
if (multiTenancySideContexes.Count == 1) | |
{ | |
return multiTenancySideContexes[0]; | |
} | |
//Try to get the DbContext which not defined AutoRepositoryTypesAttribute | |
var defaultRepositoryContexes = allTargetTypes.Where(type => !type.IsDefined(typeof(AutoRepositoryTypesAttribute), true)).ToList(); | |
if (defaultRepositoryContexes.Count == 1) | |
{ | |
return defaultRepositoryContexes[0]; | |
} | |
//Generating exception | |
if (multiTenancySideContexes.Count > 1) | |
{ | |
throw new AbpException(string.Format( | |
"Found more than one concrete type for given DbContext Type ({0}) define MultiTenancySideAttribute with {1}. Found types: {2}.", | |
sourceDbContextType, | |
currentTenancySide, | |
multiTenancySideContexes.JoinAsString(", ") | |
)); | |
} | |
throw new AbpException(string.Format( | |
"Found more than one concrete type for given DbContext Type ({0}) but none of them defines MultiTenancySideAttribute with {1}. Found types: {2}.", | |
sourceDbContextType, | |
currentTenancySide, | |
multiTenancySideContexes.JoinAsString(", ") | |
)); | |
} | |
} | |
} |
Hi! I also have the problem of "Found more than one concrete type for given dbcontext type" after I upgrade from 0.8.2.0 to 0.9.3.0. Actually, I use DD design and i have many bounded contexts based on modules i have. Those bounded contexts uses only one single database or one connection string. For 0.8.2.0 version, I can do it without any problems and no need to define a custom repository since different bounded contexts contain different entities mapping and ASP.NET Zero design is smart enough to use the right bounded context. Here, i would like to confirm, for version 0.9.3.0, do i need to define each custom repository for each bounded context i have or is there anyway I can still enjoy using one repository for all bounded contexts?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please continue on https://github.com/aspnetzero/aspnet-zero/issues/224