OK, if I understand correctly, your IDataService interface has specific methods for saving your concrete classes that implement IBaseRecover, but to call the correct save method, you need to know the concrete type of IBaseRecover. Why not push the save responsibility into the concrete implementations of IBaseRecover because they know best which method should be called. You could do this like follows:
interface IBaseRecover{
void Save();
....
}
class LoanRecovery : IBaseRecover {
private IDataService _dataService;
LoadRecovery(IDataService dataService){
_dataService = dataService;
}}
void Save(){
_dataService.InsertLoan(this);
}
}
OK, here's another thought based on your comment. I think the complexity here comes from the fact that you are using a view that can represent three different types of models, and even though they all derive from the same base class, your view has inputs that are specific to each implementation. That's fine, but I think you'd benefit from a different variation of the MVP pattern. Martin Fowler has since broken up the MVP pattern into Supervising Contoller and Passive View. I think Passive View would serve you well here. In that case, your view would expose the values of it's input elements as properties so that the Presenter could get Recovery properties such as IssueDate and Amount without have to know about the view components. So the code for the Insert Action on the view might look something like the following:
public decimal Amount{
get{
return Convert.ToDecimal(txtAmount.text);
}
}
void btnInsert_Click(Object sender, EventArgs e){
presenter.Insert();
}
Note that it's ok for your view to have an instance of the Presenter. Now the Presenter Insert method might look something like this:
public void Insert(){
if(_view.Type == "Loan"){
var model = new LoadRecovery();
model.IssueDate = _view.IssueDate;
model.Amount = _view.Amount;
_dataService.InsertLoan(model);
}
}
And if you were also first displaying a Recovery to be updated instead of inserted:
public void Show(){
_view.IssueDate = model.IssueDate;
_view.Amount = model.Amount;
}