Base solution for your next web application
Open Closed

Extending Tenant Entity as well as Tenant Cache #5818


User avatar
0
maharatha created

I am trying to add two columns to Tenant table and also trying to handle the Tenant Cache.

I am geting the below error :

Severity Code Description Project File Line Suppression State Error CS1593 Delegate 'Func<int, TenantCacheItem>' does not take 0 arguments TenantCustomCache.cs 74 Active

` ** public TenantCustomCacheItem GetOrNull(int tenantId)

{
     return _cacheManager
        .GetTenantCache()
        .Get(
            tenantId,
            () =>
            {
                var tenant = GetTenantOrNull(tenantId);
                if (tenant == null)
                {
                    return null;
                }

                return CreateTenantCacheItem(tenant);
            }
        );
}**`

Below is the entire class ` public class TenantCustomCache<TTenant, TUser> : ITenantCustomCacheItem, IEventHandler<EntityChangedEventData

    public TenantCustomCache(
        ICacheManager cacheManager,
        IRepository<TTenant> tenantRepository,
        IUnitOfWorkManager unitOfWorkManager)
    {
        _cacheManager = cacheManager;
        _tenantRepository = tenantRepository;
        _unitOfWorkManager = unitOfWorkManager;
    }

    public virtual TenantCustomCacheItem 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 TenantCustomCacheItem Get(string tenancyName)
    {
        var cacheItem = GetOrNull(tenancyName);

        if (cacheItem == null)
        {
            throw new AbpException("There is no tenant with given tenancy name: " + tenancyName);
        }

        return cacheItem;
    }

    public virtual TenantCustomCacheItem GetOrNull(string tenancyName)
    {
        var tenantId = _cacheManager
            .GetTenantByNameCache()
            .Get(
                tenancyName.ToLowerInvariant(),
                () => GetTenantOrNull(tenancyName)?.Id
            );

        return tenantId == null ? null : Get(tenantId.Value);
    }

   ** public TenantCustomCacheItem GetOrNull(int tenantId)

    {
         return _cacheManager
            .GetTenantCache()
            .Get(
                tenantId,
                () =>
                {
                    var tenant = GetTenantOrNull(tenantId);
                    if (tenant == null)
                    {
                        return null;
                    }

                    return CreateTenantCacheItem(tenant);
                }
            );
    }**

    protected virtual TenantCustomCacheItem CreateTenantCacheItem(TTenant tenant)
    {
        return new TenantCustomCacheItem
        {
            Id = tenant.Id,
            Name = tenant.Name,
            TenancyName = tenant.TenancyName,
            EditionId = tenant.EditionId,
            ConnectionString = SimpleStringCipher.Instance.Decrypt(tenant.ConnectionString),
            IsActive = tenant.IsActive,
            EncryptedAesSessionKey = tenant.EncryptedAesSessionKey,
            KeyId = tenant.KeyId

        };
    }

    [UnitOfWork]
    protected virtual TTenant GetTenantOrNull(int tenantId)
    {
        using (_unitOfWorkManager.Current.SetTenantId(null))
        {
            return _tenantRepository.FirstOrDefault(tenantId);
        }
    }

    [UnitOfWork]
    protected virtual TTenant GetTenantOrNull(string tenancyName)
    {
        using (_unitOfWorkManager.Current.SetTenantId(null))
        {
            return _tenantRepository.FirstOrDefault(t => t.TenancyName == tenancyName);
        }
    }

    public void HandleEvent(EntityChangedEventData<TTenant> eventData)
    {
        var existingCacheItem = _cacheManager.GetTenantCache().GetOrDefault(eventData.Entity.Id);

        _cacheManager
            .GetTenantByNameCache()
            .Remove(
                existingCacheItem != null
                    ? existingCacheItem.TenancyName.ToLowerInvariant()
                    : eventData.Entity.TenancyName.ToLowerInvariant()
            );

        _cacheManager
            .GetTenantCache()
            .Remove(eventData.Entity.Id);
    }


}`

10 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    You also need to modify this extension class.

    _cacheManager .GetTenantCache()

    TenantCacheManagerExtensions.cs

    public static class TenantCacheManagerExtensions
    {
    	public static ITypedCache<int, TenantCacheItem> GetTenantCache(this ICacheManager cacheManager)
    	{
    		return cacheManager.GetCache<int, TenantCacheItem>(TenantCacheItem.CacheName);
    	}
    
    	public static ITypedCache<string, int?> GetTenantByNameCache(this ICacheManager cacheManager)
    	{
    		return cacheManager.GetCache<string, int?>(TenantCacheItem.ByNameCacheName);
    	}
    }
    
  • User Avatar
    0
    maharatha created

    I have added these four classes :

    `public interface ITenantCacheExtensions { TenantCacheItemExtensions Get(int tenantId);

    TenantCacheItemExtensions Get(string tenancyName);

    TenantCacheItemExtensions GetOrNull(string tenancyName);

    TenantCacheItemExtensions GetOrNull(int tenantId);

    }``

    public class TenantCacheExtensions<TTenant, TUser> : ITenantCacheExtensions, IEventHandler<EntityChangedEventData>

    where TTenant : Tenant where TUser : AbpUserBase { private readonly ICacheManager _cacheManager; private readonly IRepository _tenantRepository;

    private readonly IUnitOfWorkManager _unitOfWorkManager;

        public TenantCacheExtensions(
            ICacheManager cacheManager,
            IRepository&lt;TTenant&gt; tenantRepository,
            IUnitOfWorkManager unitOfWorkManager)
        {
            _cacheManager = cacheManager;
            _tenantRepository = tenantRepository;
            _unitOfWorkManager = unitOfWorkManager;
        }
    
        public virtual TenantCacheItemExtensions 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 TenantCacheItemExtensions Get(string tenancyName)
        {
            var cacheItem = GetOrNull(tenancyName);
    
            if (cacheItem == null)
            {
                throw new AbpException("There is no tenant with given tenancy name: " + tenancyName);
            }
    
            return cacheItem;
        }
    
        public virtual TenantCacheItemExtensions GetOrNull(string tenancyName)
        {
            var tenantId = _cacheManager
                .GetTenantByNameCache()
                .Get(
                    tenancyName.ToLowerInvariant(),
                    () => GetTenantOrNull(tenancyName)?.Id
                );
    
            return tenantId == null ? null : Get(tenantId.Value);
        }
    
        public TenantCacheItemExtensions GetOrNull(int tenantId)
    
        {
             return _cacheManager
                .GetTenantCache()
                .Get(
                    tenantId,
                    () =>
                    {
                        var tenant = GetTenantOrNull(tenantId);
                        if (tenant == null)
                        {
                            return null;
                        }
    
                        return CreateTenantCacheItem(tenant);
                    }
                );
        }
    
        protected virtual TenantCacheItemExtensions CreateTenantCacheItem(TTenant tenant)
        {
            return new TenantCacheItemExtensions
            {
                Id = tenant.Id,
                Name = tenant.Name,
                TenancyName = tenant.TenancyName,
                EditionId = tenant.EditionId,
                ConnectionString = SimpleStringCipher.Instance.Decrypt(tenant.ConnectionString),
                IsActive = tenant.IsActive,
                EncryptedAesSessionKey = tenant.EncryptedAesSessionKey,
                KeyId = tenant.KeyId
    
            };
        }
    
        [UnitOfWork]
        protected virtual TTenant GetTenantOrNull(int tenantId)
        {
            using (_unitOfWorkManager.Current.SetTenantId(null))
            {
                return _tenantRepository.FirstOrDefault(tenantId);
            }
        }
    
        [UnitOfWork]
        protected virtual TTenant GetTenantOrNull(string tenancyName)
        {
            using (_unitOfWorkManager.Current.SetTenantId(null))
            {
                return _tenantRepository.FirstOrDefault(t => t.TenancyName == tenancyName);
            }
        }
    
        public void HandleEvent(EntityChangedEventData&lt;TTenant&gt; eventData)
        {
            var existingCacheItem = _cacheManager.GetTenantCache().GetOrDefault(eventData.Entity.Id);
    
            _cacheManager
                .GetTenantByNameCache()
                .Remove(
                    existingCacheItem != null
                        ? existingCacheItem.TenancyName.ToLowerInvariant()
                        : eventData.Entity.TenancyName.ToLowerInvariant()
                );
    
            _cacheManager
                .GetTenantCache()
                .Remove(eventData.Entity.Id);
        }
    
    
    }`
    
    `
        public object CustomData { get; set; }
    
        public byte[] EncryptedAesSessionKey { get; set; }
    
        public string KeyId { get; set; }
    }`
    
    `public static class TenantCacheManagerExtensions
    {
        public static ITypedCache&lt;int, TenantCacheItemExtensions&gt; GetTenantCache(this ICacheManager cacheManager)
        {
            return cacheManager.GetCache&lt;int, TenantCacheItemExtensions&gt;(TenantCacheItemExtensions.CacheName);
        }
    
        public static ITypedCache&lt;string, int?&gt; GetTenantByNameCache(this ICacheManager cacheManager)
        {
            return cacheManager.GetCache&lt;string, int?&gt;(Abp.MultiTenancy.TenantCacheItem.ByNameCacheName);
        }
    }`
    

    Then I made changes to ITenanctCache in TokenAuthController

    `public class TokenAuthController : EDRMSControllerBase { private const string UserIdentifierClaimType = "http://aspnetzero.com/claims/useridentifier";

        private readonly LogInManager _logInManager;
        private readonly ITenantCacheExtensions _tenantCache;`
    

    When I do this I get Internal Server error, when I change it to ITenantCache it works fine.

    Am i missing something ?

  • User Avatar
    0
    aaron created
    Support Team
    • Four? I see three. (Please format code properly.)
    • For internal server error, always check Logs.txt.
    • TenantCacheExtensions must not be generic if you expect ABP to register it by convention.
  • User Avatar
    0
    maharatha created
    public interface ITenantCacheExtensions 
        {
            TenantCacheItemExtensions Get(int tenantId);
    
            TenantCacheItemExtensions Get(string tenancyName);
    
            TenantCacheItemExtensions GetOrNull(string tenancyName);
    
            TenantCacheItemExtensions GetOrNull(int tenantId);
    
        }
    
    public class TenantCacheExtensions<TTenant, TUser> : ITenantCacheExtensions, IEventHandler<EntityChangedEventData<TTenant>>
           where TTenant : AbpTenant<TUser>
           where TUser : AbpUserBase
        {
            private readonly ICacheManager _cacheManager;
            private readonly IRepository<TTenant> _tenantRepository;
            private readonly IUnitOfWorkManager _unitOfWorkManager;
    
            public TenantCacheExtensions(
                ICacheManager cacheManager,
                IRepository<TTenant> tenantRepository,
                IUnitOfWorkManager unitOfWorkManager)
            {
                _cacheManager = cacheManager;
                _tenantRepository = tenantRepository;
                _unitOfWorkManager = unitOfWorkManager;
            }
    
            public virtual TenantCacheItemExtensions 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 TenantCacheItemExtensions Get(string tenancyName)
            {
                var cacheItem = GetOrNull(tenancyName);
    
                if (cacheItem == null)
                {
                    throw new AbpException("There is no tenant with given tenancy name: " + tenancyName);
                }
    
                return cacheItem;
            }
    
            public virtual TenantCacheItemExtensions GetOrNull(string tenancyName)
            {
                var tenantId = _cacheManager
                    .GetTenantByNameCache()
                    .Get(
                        tenancyName.ToLowerInvariant(),
                        () => GetTenantOrNull(tenancyName)?.Id
                    );
    
                return tenantId == null ? null : Get(tenantId.Value);
            }
    
            public TenantCacheItemExtensions GetOrNull(int tenantId)
    
            {
                 return _cacheManager
                    .GetTenantCache()
                    .Get(
                        tenantId,
                        () =>
                        {
                            var tenant = GetTenantOrNull(tenantId);
                            if (tenant == null)
                            {
                                return null;
                            }
    
                            return CreateTenantCacheItem(tenant);
                        }
                    );
            }
    
            protected virtual TenantCacheItemExtensions CreateTenantCacheItem(TTenant tenant)
            {
                return new TenantCacheItemExtensions
                {
                    Id = tenant.Id,
                    Name = tenant.Name,
                    TenancyName = tenant.TenancyName,
                    EditionId = tenant.EditionId,
                    ConnectionString = SimpleStringCipher.Instance.Decrypt(tenant.ConnectionString),
                    IsActive = tenant.IsActive,
                    EncryptedAesSessionKey = tenant.EncryptedAesSessionKey,
                    KeyId = tenant.KeyId
    
                };
            }
    
            [UnitOfWork]
            protected virtual TTenant GetTenantOrNull(int tenantId)
            {
                using (_unitOfWorkManager.Current.SetTenantId(null))
                {
                    return _tenantRepository.FirstOrDefault(tenantId);
                }
            }
    
            [UnitOfWork]
            protected virtual TTenant GetTenantOrNull(string tenancyName)
            {
                using (_unitOfWorkManager.Current.SetTenantId(null))
                {
                    return _tenantRepository.FirstOrDefault(t => t.TenancyName == tenancyName);
                }
            }
    
            public void HandleEvent(EntityChangedEventData<TTenant> eventData)
            {
                var existingCacheItem = _cacheManager.GetTenantCache().GetOrDefault(eventData.Entity.Id);
    
                _cacheManager
                    .GetTenantByNameCache()
                    .Remove(
                        existingCacheItem != null
                            ? existingCacheItem.TenancyName.ToLowerInvariant()
                            : eventData.Entity.TenancyName.ToLowerInvariant()
                    );
    
                _cacheManager
                    .GetTenantCache()
                    .Remove(eventData.Entity.Id);
            }
    
    
        }
    
    [Serializable]
        public class TenantCacheItemExtensions
        {
            public const string CacheName = "AbpZeroTenantCache";
    
            public const string ByNameCacheName = "AbpZeroTenantByNameCache";
    
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public string TenancyName { get; set; }
    
            public string ConnectionString { get; set; }
    
            public int? EditionId { get; set; }
    
            public bool IsActive { get; set; }
    
            public object CustomData { get; set; }
    
            public byte[] EncryptedAesSessionKey { get; set; }
    
            public string KeyId { get; set; }
        }
    
     public static class TenantCacheManagerExtensions
        {
            public static ITypedCache<int, TenantCacheItemExtensions> GetTenantCache(this ICacheManager cacheManager)
            {
                return cacheManager.GetCache<int, TenantCacheItemExtensions>(TenantCacheItemExtensions.CacheName);
            }
    
            public static ITypedCache<string, int?> GetTenantByNameCache(this ICacheManager cacheManager)
            {
                return cacheManager.GetCache<string, int?>(Abp.MultiTenancy.TenantCacheItem.ByNameCacheName);
            }
        }
    
  • User Avatar
    0
    maharatha created

    I added these classes in the core project.

    Error in Error Log :

    <br> TokenAuthController' is waiting for the following dependencies: - Service 'DOCUHOLD.EDRMS.MultiTenancy.Cache.ITenantCacheExtensions' which was not registered.

    Castle.MicroKernel.Handlers.HandlerException: Can't create component 'DOCUHOLD.EDRMS.Web.Controllers.TokenAuthController' as it has dependencies to be satisfied.

    I know I am missing something somewhere but not sure where and how to register it.

  • User Avatar
    0
    maharatha created

    Any updates?

  • User Avatar
    0
    maharatha created

    Hi -

    Can I get an answer to my question ? Thank you in advance.

  • User Avatar
    0
    maliming created
    Support Team

    hi @maharatha

    Can you use MVC's Demo project template to reproduce the problems you encountered and then share the project? email: [email protected]

  • User Avatar
    0
    maharatha created

    I have already sent you an email. Did you get a chance to look at it ?

  • User Avatar
    0
    maliming created
    Support Team

    I will check it out today.