I have added a domain property to the Tenant class and have replicated the ITenantCache implementation to now have Get(string domain) instead of Get(string tenancyName).
After making all the changes so it looks up the tenant based on the domain instead of the tenancy name I am unable to get access to the new Domain property.
<ins>protected virtual TTenant GetTenantOrNull(string domain)
{
using (_unitOfWorkManager.Current.SetTenantId(null))
{
return _tenantRepository.FirstOrDefault(t => t.**[u]_Domain_</ins>**== domain);
}
}
I have the same issue for the below
protected virtual RbTenantCacheItem CreateRbTenantCacheItem(TTenant tenant)
{
return new RbTenantCacheItem
{
Id = tenant.Id,
Name = tenant.Name,
TenancyName = tenant.TenancyName,
Domain = tenant.<ins>_**Domain**_</ins>,
EditionId = tenant.EditionId,
ConnectionString = SimpleStringCipher.Instance.Decrypt(tenant.ConnectionString),
IsActive = tenant.IsActive
};
}
Below is the full class
public class TenantCache<TTenant, TUser> : IRbTenantCache, IEventHandler<EntityChangedEventData<TTenant>>
where TTenant : AbpTenant<TUser>
where TUser : AbpUser<TUser>
{
private readonly ICacheManager _cacheManager;
private readonly IRepository<TTenant> _tenantRepository;
private readonly IUnitOfWorkManager _unitOfWorkManager;
public TenantCache(
ICacheManager cacheManager,
IRepository<TTenant> tenantRepository,
IUnitOfWorkManager unitOfWorkManager)
{
_cacheManager = cacheManager;
_tenantRepository = tenantRepository;
_unitOfWorkManager = unitOfWorkManager;
}
public virtual RbTenantCacheItem Get(int tenantId)
{
var cacheItem = GetOrNull(tenantId);
if (cacheItem == null)
{
throw new AbpException("There is no tenant with given id: " + tenantId);
}
return cacheItem;
}
public virtual RbTenantCacheItem Get(string domain)
{
var cacheItem = GetOrNull(domain);
if (cacheItem == null)
{
throw new AbpException("There is no tenant with given tenancy name: " + domain);
}
return cacheItem;
}
public virtual RbTenantCacheItem GetOrNull(string domain)
{
var tenantId = _cacheManager.GetTenantByNameCache()
.Get(domain, () => GetTenantOrNull(domain)?.Id);
if (tenantId == null)
{
return null;
}
return Get(tenantId.Value);
}
public RbTenantCacheItem GetOrNull(int tenantId)
{
return _cacheManager
.GetTenantCache()
.Get(
tenantId,
() =>
{
var tenant = GetTenantOrNull(tenantId);
if (tenant == null)
{
return null;
}
return CreateRbTenantCacheItem(tenant);
}
);
}
protected virtual RbTenantCacheItem CreateRbTenantCacheItem(TTenant tenant)
{
return new RbTenantCacheItem
{
Id = tenant.Id,
Name = tenant.Name,
TenancyName = tenant.TenancyName,
Domain = tenant.Domain,
EditionId = tenant.EditionId,
ConnectionString = SimpleStringCipher.Instance.Decrypt(tenant.ConnectionString),
IsActive = tenant.IsActive
};
}
[UnitOfWork]
protected virtual TTenant GetTenantOrNull(int tenantId)
{
using (_unitOfWorkManager.Current.SetTenantId(null))
{
return _tenantRepository.FirstOrDefault(tenantId);
}
}
[UnitOfWork]
protected virtual TTenant GetTenantOrNull(string domain)
{
using (_unitOfWorkManager.Current.SetTenantId(null))
{
return _tenantRepository.FirstOrDefault(t => t.Domain == domain);
}
}
public void HandleEvent(EntityChangedEventData<TTenant> eventData)
{
var existingCacheItem = _cacheManager.GetTenantCache().GetOrDefault(eventData.Entity.Id);
_cacheManager
.GetTenantByNameCache()
.Remove(
existingCacheItem != null
? existingCacheItem.TenancyName
: eventData.Entity.TenancyName
);
_cacheManager
.GetTenantCache()
.Remove(eventData.Entity.Id);
}
}
3 Answer(s)
-
0
Hi,
Instead of using
where TTenant : AbpTenant<TUser>
can you try with
where TTenant : Tenant
in your custom tenant cache class ?
-
0
Thanks for pointing that out.
One more question. If I wanted to use this class with IOC where should I register it (if I need to) and do I have to use the constructor approach or is there another way to use the class?
I have created a filter to retrieve the cached version of the Tenant using the domain. Alternatively, if I have to use the constructor approach I will have to put it in the in the base controller.
-
0
Hi,
You can derive your class from ISingletonDependency or ITransientDependency. It will be registered to DI automatically by ABP.
If you want to do it manually, you can do it in the Initialize of your ABP module using IocManager.
Other than constructor injection there is property injection which you can use. You can find more info about Dependency Injection here <a class="postlink" href="http://aspnetboilerplate.com/Pages/Documents/Dependency-Injection">http://aspnetboilerplate.com/Pages/Docu ... -Injection</a>
it's better to use constructor injection most of the times.