Im dealing with this problem.
I have base class Worker
that is abstract. Its base class for Driver
and AmountBonus
. That Bonus
is writed based on Decorator design pattern. My decorator decorate one of property from Worker
.
How it looks in code:
public abstract class Worker {}
public class Driver : Worker {}
public abstract class Bonus : Worker
{
public Bonus(Worker worker) => this.worker = worker; //constructor
//decorator on worker's property
}
public class AmountBonus : Bonus
{
public AmountBonus(Worker worker) : base(worker: worker){ } //constructor
}
Im making WebApi
app. I operate in data by endpoints. That is my PUT
request:
// PUT: api/Bonus/Amount/5
[HttpPut("Amount/{id}")]
public Worker Get(int id)
{
var worker = _context.Workers.Find(id);
switch (worker)
{
case Driver d:
worker = new AmountBonus(worker) { Id = id };
//exception here
_context.Entry((Driver)worker).State = EntityState.Modified;
_context.SaveChanges();
break;
}
return worker;
}
It is obviious, that i get:
System.InvalidCastException: 'Unable to cast object of type '....Models.Bonus.AmountBonus' to type '...Models.Driver'.'
But my question is, is it any posibilities to vast that Driver
object type? I needed it to edit exact same row in my database. My dbo.Workers
column have column Discriminator
made by Entity Framework Core and i need to have values like Driver
, Farmer
etc that i made and didnt mentioned in this example.
I Could make an Entity for my AmountBonus
that i said, i need to have origin object type in my database. And i need to use Decorator there. Any ideas, how i can do it? Is it possible, to keep origin Type
?
You are passing actual valid worker instance to the decorator.
Make any change, decorator do, to that provided instance.
Then you will be able to save modified instance to the database.
[HttpPut("Amount/{id}")]
public Worker Get(int id)
{
var worker = _context.Workers.Find(id);
switch (worker)
{
case Driver d:
var amountBonus = new AmountBonus(worker) { Id = id };
amountBonus.ExecuteDecoration();
_context.Entry(worker).State = EntityState.Modified;
_context.SaveChanges();
break;
}
return Ok(worker);
}
AmountBonus
class does not even need to inherit from Worker
. Your casting problem goes away itself then
Then it look more like Visitor pattern for me ;)
What you're doing makes no sense. Decorators are utility classes; they overlay programmatic functionality on to the classes they decorate. They are not something that can nor should be persisted to something like a database.
In other words, if your object is a Driver
, then you need to keep it a Driver
, not wrap it in an AmountBonus
decorator and then attempt to persist that. Later, if you need whatever functionality the AmountBonus
decorator adds again, you simply wrap your Driver
instance in it again.
It doesn't even look like you're doing anything interesting with the decorator here, but if there is something that occurs just by the act of wrapping a Driver
instance, then you'll need to fetch out somehow that wrapped Driver
instance afterwards to actually save that and not your decorator.