I am trying to make a generic method for the following code:
foreach (var glitter in glitterpurchase.GlitterPurchaseDetails)
{
var glitterInventory = _db.GlitterInventoriesRepository.GetAll(m => m.GlitterId == glitter.GlitterId);
if (!glitterInventory.Any())
{
var newInventory = new GlitterInventory
{
GlitterId = glitter.GlitterId,
Quantity = glitter.Quantity,
TotalAmount = (decimal)glitter.Quantity * glitter.UnitPrice,
UnitPrice = glitter.UnitPrice,
CreatedBy = User.Identity.Name,
CreatedDate = DateTime.Now,
};
_db.GlitterInventoriesRepository.Insert(newInventory);
}
else
{
var updateInventory = glitterInventory.First();
updateInventory.Quantity += glitter.Quantity;
updateInventory.TotalAmount += (decimal)glitter.Quantity * glitter.UnitPrice;
updateInventory.UnitPrice = (decimal)updateInventory.Quantity / updateInventory.TotalAmount;
updateInventory.UpdatedBy = User.Identity.Name;
updateInventory.UpdatedDate = DateTime.Now;
_db.GlitterInventoriesRepository.Update(updateInventory);
}
}
The code above just simply updates the inventory. I want to make a generic method so that I can just call that method and update the inventory of different items ( classes ). I am not good with generics and after researching I have written the following code:
public virtual void UpdateInventory<PurchasedEntity, Inventory>(IEnumerable<PurchasedEntity> purchaseDetails, GenericRepository<Inventory> inventory, Expression<Func<Inventory, bool>> filterForInventory)
where PurchasedEntity : class
where Inventory : class
{
foreach (var item in purchaseDetails)
{
var glitterInventory = inventory.GetAll(filterForInventory);
if (!glitterInventory.Any())
{
var newInventory = (Inventory)Activator.CreateInstance(typeof(Inventory), new object[]
{
GlitterId = item.GlitterId,
Quantity = item.Quantity,
TotalPrice = (decimal)item.Quantity * item.UnitPrice,
UnitPrice = item.UnitPrice,
CreatedBy = User.Identity.Name,
CreatedDate = DateTime.Now,
});
inventory.Insert(newInventory);
}
else
{
var updateInventory = glitterInventory.First();
updateInventory.Quantity += item.Quantity;
updateInventory.TotalAmount += (decimal)item.Quantity * item.UnitPrice;
updateInventory.UnitPrice = (decimal)updateInventory.Quantity / updateInventory.TotalAmount;
updateInventory.UpdatedBy = User.Identity.Name;
updateInventory.UpdatedDate = DateTime.Now;
inventory.Update(updateInventory);
}
}
}
The problem is that I am getting the following error:
'PurchasedEntity' does not contain a definition for 'GlitterId' and no extension method 'GlitterId' accepting a first argument of type 'PurchasedEntity' could be found (are you missing a using directive or an assembly reference?)
How can I remove this error and get the properties of the class generically?
I don't even know if the code I wrote is any good, so kindly if you can improve it, that would be great. Thanks.
I'm assuming not every PurchasedEntity has a GlitterId (and probably shouldn't depending on your domain). So, define a suitable Id property on PurchasedEntity (or better yet extract it to an interface):
interface IPurchasedEntity{
Guid Id {get;}
}
Update GlitterInventory to implement IPurchasedEntity:
public class GlitterInventory : IPurchasedEntity{
Guid IPurchasedEntity.Id { get{ return GlitterId; }}
}
Then your UpdateInventory method should read Id instead of GlitterId:
public virtual void UpdateInventory<PurchasedEntity, Inventory>(
IEnumerable<PurchasedEntity> purchaseDetails,
GenericRepository<Inventory> inventory,
Expression<Func<Inventory, bool>> filterForInventory)
where PurchasedEntity : IPurchasedEntity, class
where Inventory : IPurchasedEntity, class, new()
{
foreach (var item in purchaseDetails)
{
var inventory = new Inventory();
inventory.Id = item.Id;
// if you have more standard fields, define them in IPurchasedEntity
}
}
Update: After trying to infer your domain from PurcahsedEntity and Inventory it might make more sense to call IPurchasedEntity IInventory instead and define your common properties there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With