For example, @L() isn't this somewhere referring to a class in the solution that connects to the Db? I was planning to do something similar.
A separate IVisibilityChecker and VisibilityChecker classes, inject them into the base View Page, then be able to access the IfShown or IfHidden, etc.
Other way around, is in the header of the .cshtml file, I might also create an instance of some class that connects to Db.
Thanks
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.
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