Reputation: 3360
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.
Upvotes: 3
Views: 115
Reputation: 12315
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.
Upvotes: 1