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

Activities of "bilalhaidar"

Excellent! That's what I was hoping it will work.

Then, I will use one of the DbContexts only to update database, not both will do that.

Shall I set "SetInitializer(null)" in the Module class, inside the module that I want it to just "READ" from the db and ot change any table structure? Or no need?

Regards Bilal

Great.

Assuming I have 2 business modules.

Module 1: Contains entities like Car, Driver, etc. (all detailed properties) Module 2: Requires an entity Car but not all of the properties maybe only Id, Name.

I could create 2 DB Contexts, one in each project. Also, I will have entity Car defined in 2 places, in the first module with all properties and in the second module with only Id and Name.

Module 1 will be responsible for creating the tables in DB in this case.

So, in this case, I have 2 BaseRepositories each targeting a different DbContext. However, same entity like Car will appear in 2 DbContext.

Going back to the source code you referred me to,:

var primaryKeyType = EntityHelper.GetPrimaryKeyType(entityTypeInfo.EntityType);
                if (primaryKeyType == typeof(int))
                {
                    var genericRepositoryType = autoRepositoryAttr.RepositoryInterface.MakeGenericType(entityTypeInfo.EntityType);
                    if (!iocManager.IsRegistered(genericRepositoryType))
                    {
                        var implType = autoRepositoryAttr.RepositoryImplementation.GetGenericArguments().Length == 1
                                ? autoRepositoryAttr.RepositoryImplementation.MakeGenericType(entityTypeInfo.EntityType)
                                : autoRepositoryAttr.RepositoryImplementation.MakeGenericType(entityTypeInfo.DeclaringType, entityTypeInfo.EntityType);

                        iocManager.Register(
                            genericRepositoryType,
                            implType,
                            DependencyLifeStyle.Transient
                            );
                    }
                }

This means that IRepository<Car> would map to EfRepository<Module1DbContext, Car, int>. So Module1RepositoryBase will be created based on EfRepository<Module1DbContext, Car, int>.

Now, in Module 2, given the code referenced above, we will have something similar: IRepository<Car> would map to EfRepository<Module3DbContext, Car, int>. So Module3RepositoryBase will be created based on EfRepository<Module2DbContext, Car, int>.

Now, in the code, how would it know which DbContext to use?

Thanks

Do you have a similar case in the framework where you needed to call the Database from the Razor View? I can at least follow the code and see the way you thought about it.

Thanks, Bilal

Hi, I am facing a big issue now with this design! I will paste the code here and tell you where the problem is.

I've highlighted in bold the method that I dunno how to proceed from now on. I followed the pattern you use in some of the classes to create a manager and using caching also.

I am stuck here and really appreciate your assistance.

Regards Bilal

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;
        }
    }

    public class HostEntityWithIntKeyBase : HostEntityBase<int>
    {

    }

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;
        }
    }

    /// <summary>
    /// Used to cache HostEntities
    /// </summary>
    public class HostEntityCacheItem
    {
        public const string CacheStoreName = "DrcHostEntities";

        public List<HostEntityCacheItemSingle> Items { get; set; }

        public HostEntityCacheItem()
        {
            Items = new List<HostEntityCacheItemSingle>();
        }

    }

    public class HostEntityCacheItemSingle
    {
        public object Id { get; set; }
        public string Label { get; set; }
        public string Notes { get; set; }
    }

    public static class DrcCacheManagerExtensions
    {
        public static ITypedCache<string, HostEntityCacheItem> GetHostEntityCache(this ICacheManager cacheManager)
        {
            return cacheManager.GetCache<string, HostEntityCacheItem>(HostEntityCacheItem.CacheStoreName);
        }
    }

    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()
        {
            return (await GetListAsync());
        }
}
**[UnitOfWork]
        private async Task<List<THostEntityBase>> GetListAsync()
        {
            var entity = await GetListFromCacheAsync();

            var instances = new List<THostEntityBase>();

            foreach(HostEntityCacheItemSingle e in entity.Items)
            {
                instances.Add(new HostEntityBase<TPrimaryKey> { Id =  } );
            }

            return instances;
        }**

        [UnitOfWork]
        private async Task<HostEntityCacheItem> GetListFromCacheAsync()
        {
            return await CacheManager.GetHostEntityCache().GetAsync("0", async () =>
            {
                //Get a list from the database
                var list = (await GetHostEntityFromDatabaseAsync());

                var newItem = new HostEntityCacheItem();
                foreach (var l in list)
                {
                    newItem.Items.Add(new HostEntityCacheItemSingle { Id = l.Id, Label = l.Label, Notes = l.Notes });
                }

                return newItem;
            });
        }

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

Thanks a lot.

Answer

Hi,

I am currently using the framework with Angular js 1.x.

By default, the framework would generate Web API proxies for all those objects that implemented IAppService.

Therefore, I use the proxy on the client side to call any method defined on the ApplicationSevice layer using only DTOs.

Generally speaking, DTO is more or less a ViewModel.

HTH, Bilal

So, I would define an IDataLoader and DataLoader and then in my view, I Resolve this class and call that method on it? Or something else?

Thanks

Great. Thanks.

Is there a way to create Permissions by the Admin from the Web App? Currently, I create them inside .Core module.

Regards Bilal

Ok great. Thanks.

You are right, it depends. In my case, I am caching some reference data. However, this data might change, so I will invalidate the data once it changes. But as a manager, I only need a single instance from it, no need to have an instance every time it is being asked for.

Regards Bilal

Thanks, no need to explain it. I went through all the related classes and it makes perfect sense :)

Given the fact, the AbpDbContext could have an unknown number of IDbSet<T> ahead of time, this code is needed.

In my case, I just want to map IFoo<T> or IFoo<T,Z> to Foo<T> or Foo<T,Z>, so I use this code and it seems to be working fine.

private void RegisterForReferenceDataManager()
        {
            IocManager.RegisterIfNot(
                typeof(IReferenceDataManager<,>),
                typeof(ReferenceDataManager<,>),
                DependencyLifeStyle.Singleton);
        }

One question though, what's the recommendation to use Singleton or Transient? When will each be used?

In case I am registering the classes as above, do I still need to have Foo<T> implement ISingletonDependency? As I understand, this interface is used only when doing the below so that CW would know how to register an interface and implementation. Correct?

IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
Showing 551 to 560 of 635 entries