Base solution for your next web application
Starts in:
01 DAYS
01 HRS
01 MIN
01 SEC

Activities of "bilalhaidar"

Hi,

I am seeking your assistance.

In the .Core project, I've added the following:

public class HostEntityBase<TPrimaryKey> : FullAuditedEntity<TPrimaryKey>, IMayHaveTenant
    {
        public virtual int? TenantId { get; set; }

        [Required]
        [StringLength(HostEntityConsts.MaxLabelLength)]
        public virtual string Label { get; protected set; }

        public virtual string Notes { get; protected set; }

        public virtual void UpdateLabel(string newLabel)
        {
            //Validate newLabel
            Check.NotNull(newLabel, nameof(newLabel));

            Label = newLabel;
        }

        public virtual void UpdateNotes(string newNotes)
        {
            Notes = newNotes;
        }

        protected HostEntityBase()
        {

        }
    }

    public class HostEntityWithIntKeyBase : HostEntityBase<int>
    {

    }

 [Table("DrcClothingSize")]
    public class ClothingSize : HostEntityWithIntKeyBase, IMayHaveTenant
    {
        /// <summary>
        /// EF 
        /// </summary>
        protected ClothingSize()
        {

        }

        public static ClothingSize Create(string label, string notes = null)
        {
            var clothingSize = new ClothingSize();
            clothingSize.UpdateLabel(label);
            clothingSize.UpdateNotes(notes);

            return clothingSize;
        }
    }

   public interface IReferenceDataManager<THostEntityBase> : IReferenceDataManager<THostEntityBase, int>
    {

    }

    public interface IReferenceDataManager<THostEntityBase, TPrimaryKey> 
    {
        /// <summary>
        /// Gets a list of all available <typeparamref name="THostEntity"/> in the host
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        Task<IReadOnlyList<THostEntityBase>> GetAsync(string filter);
        
        /// <summary>
        /// Adds a <typeparamref name="THostEntity"/> record
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        Task CreateAsync(THostEntityBase input);

        /// <summary>
        /// Adds a <typeparamref name="THostEntity"/> record
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        Task UpdateAsync(THostEntityBase input);

        /// <summary>
        /// Deletes an existing <typeparamref name="THostEntity"/> record
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        Task DeleteAsync(TPrimaryKey input);
    }

    public class ReferenceDataManager<THostEntityBase> :
    ReferenceDataManager<THostEntityBase, int>,
    IReferenceDataManager<THostEntityBase>
    where THostEntityBase : HostEntityBase<int>
    {
        public ReferenceDataManager(
            ICacheManager cacheManager,
            IRepository<THostEntityBase, int> repository,
            IUnitOfWorkManager unitOfWorkManager,
            string cacheName = null)
            : base(
                cacheManager,
                repository,
                unitOfWorkManager,
                cacheName)
        {
        }
    }

    public class ReferenceDataManager<THostEntityBase, TPrimaryKey> : 
        IReferenceDataManager<THostEntityBase, TPrimaryKey>,
        ISingletonDependency
        where THostEntityBase : HostEntityBase<TPrimaryKey>
    {
        public string CacheName { get; private set; }

        protected ICacheManager CacheManager { get; private set; }

        protected IUnitOfWorkManager UnitOfWorkManager { get; private set; }

        protected IRepository<THostEntityBase, TPrimaryKey> Repository { get; private set; }

        public ReferenceDataManager(ICacheManager cacheManager,
            IRepository<THostEntityBase, TPrimaryKey> repository,
            IUnitOfWorkManager unitOfWorkManager,
            string cacheName = null)
        {
            UnitOfWorkManager = unitOfWorkManager;
            Repository = repository;
            CacheManager = cacheManager;
            CacheName = cacheName ?? GenerateDefaultCacheName();
        }

        public virtual async Task<IReadOnlyList<THostEntityBase>> GetAsync(string filter = null)
        {
            return (await GetListAsync(filter));
        }

        [UnitOfWork]
        public virtual async Task CreateAsync(THostEntityBase input)
        {
            if ( (await GetAsync() as IReadOnlyList<THostEntityBase>)
                .Any(t => t.Label.ToLower().Contains(input.Label.ToLower())))
            {
                throw new AbpException($"There is already an entity with Label = {input.Label}");
            }

            var existingEntity = (await GetAsync(input.Label));
            if (existingEntity != null)
            {

            }
            using (UnitOfWorkManager.Current.SetTenantId(null))
            {
                await Repository.InsertAsync(input);
                await UnitOfWorkManager.Current.SaveChangesAsync();
            }

        }

        [UnitOfWork]
        public virtual async Task UpdateAsync(THostEntityBase input)
        {
            //Check the entity doesnt exist
            var existingEntity = ((await GetAsync() as IReadOnlyList<THostEntityBase>)
                .FirstOrDefault(t => t.Label.ToLower().Contains(input.Label.ToLower())));

            if (existingEntity != null)
            {
                if (!existingEntity.Id.Equals(input.Id))
                {
                    throw new AbpException($"There is already an entity with Label = {input.Label}");
                }
            }

            existingEntity.UpdateLabel(input.Label.Trim());
            existingEntity.UpdateNotes(input.Notes.Trim());

            using (UnitOfWorkManager.Current.SetTenantId(null))
            {
                await Repository.UpdateAsync(existingEntity);
                await UnitOfWorkManager.Current.SaveChangesAsync();
            }
        }

        [UnitOfWork]
        public virtual async Task DeleteAsync(TPrimaryKey input)
        {
            //Get all records from cache
            var existingEntity = (await GetAsync() as IReadOnlyList<THostEntityBase>).FirstOrDefault(t => t.Id.Equals(input));
            if (existingEntity == null)
            {
                return;
            }

            using (UnitOfWorkManager.Current.SetTenantId(null))
            {
                await Repository.DeleteAsync(existingEntity.Id);
                await UnitOfWorkManager.Current.SaveChangesAsync();
            }
        }

        [UnitOfWork]
        private async Task<List<THostEntityBase>> GetListAsync(string filter)
        {
            //Get THostEntityBase from host not any specific tenant
            using (UnitOfWorkManager.Current.SetTenantId(null))
            {
                return await Repository
                                .GetAllListAsync(
                                    WithFitler(filter)
                                );
            }
        }

        /// <summary>
        /// Prepares a dynamic filter to insert into GetAllListAsync
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        private Expression<Func<THostEntityBase, bool>> WithFitler(string filter)
        {
            if (filter.IsNullOrEmpty())
            {
                return (t => true);
            }

            return (t => t.Label.ToLower().Contains(filter.ToLower()) || t.Notes.ToLower().Contains(filter.ToLower()));
        }

        protected virtual string GenerateDefaultCacheName()
        {
            return GetType().FullName;
        }
    }

This is just a ReferenceDataManager class that can handle Reading/Updating/Deleting/Creating for all objects that inherit from HostEntityBase.

Now in the .Application project, I have the following:

public interface IClothingSizeAppService : IApplicationService
    {
        /// <summary>
        /// Gets a list of all available ClothingSizes in the host
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        Task<GetClothingSizesOutput> GetClothingSizes(GetClothingSizeInput input);
        
        /// <summary>
        /// Adds or updates a clothing size record
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        Task CreateOrUpdateClothingSize(CreateOrUpdateClothingSizeInput input);

        /// <summary>
        /// Deletes an existing ClothingSize record
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        Task DeleteClothingSize(EntityDto input);
    }

    [AbpAuthorize(AppPermissions.Pages_HOSTREFDATA_CLOTHINGSIZE)]
    public class ClothingSizeAppService : OnlineSystemsAppServiceBase, IClothingSizeAppService
    {
        private readonly IReferenceDataManager<ClothingSize> _clothingSizeManager;
        private readonly ICacheManager _cacheManager;
        private readonly IRepository<ClothingSize> _repository;
        private readonly IUnitOfWorkManager _unitOfWorkManager;


        public ClothingSizeAppService(ICacheManager cacheManager,
            IRepository<ClothingSize> repository,
            IUnitOfWorkManager unitOfWorkManager)
        {
            _cacheManager = cacheManager;
            _repository = repository;
            _unitOfWorkManager = unitOfWorkManager;
            _clothingSizeManager = new ReferenceDataManager<ClothingSize>(_cacheManager, _repository, _unitOfWorkManager, "ClothingSizes");
        }

        public async Task<GetClothingSizesOutput> GetClothingSizes(GetClothingSizeInput input)
        {
            var clothingSizes = await _clothingSizeManager.GetAsync(input.Filter);

            return new GetClothingSizesOutput
            {
                 Items = clothingSizes.MapTo<List<ClothingSizeListDto>>()
            };
        }

        public async Task CreateOrUpdateClothingSize(CreateOrUpdateClothingSizeInput input)
        {
            if (input.ClothingSize.Id.HasValue)
            {
                await UpdateClothingSizeAsync(input);
            }
            else
            {
                await CreateClothingSize(input);
            }
        }

        [AbpAuthorize(AppPermissions.Pages_HOSTREFDATA_CLOTHINGSIZE_DELETE)]
        public async Task DeleteClothingSize(EntityDto input)
        {
            var existingClothingSize = await _repository.GetAsync(input.Id);

            if (existingClothingSize == null)
            {
                return;
            }

            await _clothingSizeManager.DeleteAsync(input.Id);
        }

        #region Private methods

        [AbpAuthorize(AppPermissions.Pages_HOSTREFDATA_CLOTHINGSIZE_EDIT)]
        private async Task CreateClothingSize(CreateOrUpdateClothingSizeInput input)
        {
            var newClothingSize = ClothingSize.Create(input.ClothingSize.Label, input.ClothingSize.Notes);

            //Check that this new clothing size doesn't exist
            await CheckClothingSizeIfAlreadyExists(newClothingSize.Label);

            await _clothingSizeManager.CreateAsync(newClothingSize);
        }

        [AbpAuthorize(AppPermissions.Pages_HOSTREFDATA_CLOTHINGSIZE_EDIT)]
        private async Task UpdateClothingSizeAsync(CreateOrUpdateClothingSizeInput input)
        {
            //Check that this new clothing size doesn't exist
            await CheckClothingSizeIfAlreadyExists(input.ClothingSize.Label, input.ClothingSize.Id);

            var existingClothingSize = await _repository.GetAsync(input.ClothingSize.Id.Value);
            existingClothingSize.UpdateLabel(input.ClothingSize.Label);
            existingClothingSize.UpdateNotes(input.ClothingSize.Notes);

            await _clothingSizeManager.UpdateAsync(existingClothingSize);
        }

        private async Task CheckClothingSizeIfAlreadyExists(string label, int? expectedId = null)
        {
            var allClothingSizes = await _clothingSizeManager.GetAsync(label);

            var existingClothingSize = allClothingSizes.Count > 0 ? allClothingSizes[0] : null;

            if (existingClothingSize == null)
            {
                return;
            }

            if (expectedId != null && existingClothingSize.Id == expectedId.Value)
            {
                return;
            }

            throw new UserFriendlyException(L("ThisClothingsizeAlreadyExists", label));
        }
        #endregion
    }

The problem is in this line:

public ClothingSizeAppService(ICacheManager cacheManager,
            IRepository<ClothingSize> repository,
            IUnitOfWorkManager unitOfWorkManager)
        {
            _cacheManager = cacheManager;
            _repository = repository;
            _unitOfWorkManager = unitOfWorkManager;
            _clothingSizeManager = new ReferenceDataManager<ClothingSize>(_cacheManager, _repository, _unitOfWorkManager, "ClothingSizes");
        }

I would like to be able to inject IReferenceDataManager<ClothingSize> to the constructor.

I have also another 7 similar classes to ClothingSize and all have the same behavior and share the same object properties. So I thought of creating such a generic way of handling stuff.

Then on the ApplicationService level, I would create a new AppService per Entity.

I know that the framework is already doing it with IRepository<Entity> and others.

Can you please guide me on how to do the same in my custom code?

Many Thanks, Bilal

Hi,

I want to check the HTML/js/css for some features used in the metronic theme. Are those files freely available? If not, what's the workaround here?

Thanks

Hi, I was checking this github: <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/MultipleDbContextDemo">https://github.com/aspnetboilerplate/as ... ontextDemo</a>

I am wondering, how would IRepository<Person> make use of "Default" DbContext, while IRepository<Course> make use of "Second" DbContext?

How do you direct each IRepository to use a different DbContext?

Thanks

Question

Hi,

I am browsing Metronic Theme online and I can see it has a lot of UI things to make use in an application.

When I want to use a certain feature of that theme, shall I do any extra thing to integrate with Abp? Or I can simply check the HTML/JS code from the online demo of Metronic and use the same in my app?

For instance, the Modal control, which one Abp boilertplate is using? Ui-Bootstrap or the one from Metronic?

Thanks

Hi,

How can I organize my code through VS Projects in such a way:

1- I want to separate "business modules" by VS Solution 2- Every VS Solution would contain (.Core), (.EntityFramework) and (.Application)

This way, multiple developers can work on separate "business modules" at the same time.

Looking forward to hearing your recommendations.

Regards Bilal

Hi,

I need to add custom validation to DTOs and Entities. This validation cannot be satisfied by the usual Data Annotations.

Is it okay to access DB when inside DTO or Entity to get some data from the database and then validate the object?

Is there a better way of doing it, the boilerplate way?

Thanks

Hi,

In one of the forms I am working on. I need to show/hide fields. The data to show/hide fields is stored in the database, so for example, Field 1 - Show, Field 2 - Hide.

So in the cshtml view (Angular view) I need to load this info from the database. Is this doable?

The reason I am asking is because this .cshtml view is used by Angular not a normal MVC View that I can pass a Model to it.

Thanks

Question

Hi,

I clicked on Forgot Password to retrieve the password for one of the users. I enter the tenant name and email and I receive the email.

Then, when I click on the link inside the email, it opens as follows:

http://localhost:6240/Default./Account/ResetPassword?userId=sLwljR%2FBdR7W64QgwVFk%2Bw%3D%3D&tenantId=mFlm%2BKHDrbFA%2BQWcyocM9g%3D%3D&resetCode=9748642471e34c738bea375aefa66c86

And the page shows something like:

What's wrong?

Hi, I read somewhere that the Module Zero() makes use of the Database to store Application Language Texts.

Now, in the template I downloaded, it makes use of Embedded Application Language Text files.

My question is, isn't this template using Module Zero()? If not, how can i store Application Language Texts in Database?

Thanks

Hello, in this source code below, the class already inherits from MyTestsDomainServiceBase, hence, all methods are handled automatically by UOW.

Why the code still adds an attribute [UnitOfWork], is it necessary in this case?

Thanks

public class FriendshipManager : MyTestsDomainServiceBase, IFriendshipManager
    {
        private readonly IRepository<Friendship, long> _friendshipRepository;

        public FriendshipManager(IRepository<Friendship, long> friendshipRepository)
        {
            _friendshipRepository = friendshipRepository;
        }

        [UnitOfWork]
        public void CreateFriendship(Friendship friendship)
        {
            if (friendship.TenantId == friendship.FriendTenantId &&
                friendship.UserId == friendship.FriendUserId)
            {
                throw new UserFriendlyException(L("YouCannotBeFriendWithYourself"));
            }

            using (CurrentUnitOfWork.SetTenantId(friendship.TenantId))
            {
                _friendshipRepository.Insert(friendship);
                CurrentUnitOfWork.SaveChanges();
            }
        }
Showing 151 to 160 of 174 entries