I'd like to decouple BL from DAL. Especially i want to have primary key protected (I don't want my business users to modify Item.Id).
In my DataLayer (let's imagine it is a simple sql table with autogenerated primary key) I try to insert item and update item.Id. Of course I can't because it is protected property.
Is there a way to do this without using a reflection? (I mean maybe my architecture is wrong...)
BusinessLayer:
public class Item
{
public int Id { get; protected set; }
public string Name { get; set; }
}
public interface IRepository<Item>
{
void Insert(Item item);
//and other CRUD operations
}
DataLayer (using EntityFramework with sqlserver):
public class EfRepository : IRepository<Item>
{
EfContext ctx;
public void Insert(Item item)
{
//EfContext uses its ItemEntity, so I have to map Item to EntityItem
var mapped = AutoMapper.Map<Item, EntityItem>(item);
ctx.Items.Add(mapped);
//after this operation EF will set primary key to mapped object
//and now I need to set this to primary key to my business
//domain object.
item.Id = ?? // can't set protected property!!!
}
}
To protect your logic against accidental modifications Id
you can use "property injection pattern":
public class Item
{
public Item()
{
_id = -1;
}
public int Id
{
get
{
return _id;
}
set
{
if (_id != -1)
{
throw new OperationException("Item.Id has already been set");
}
_id = value;
}
}
public string Name { get; set; }
}