In a module of a win forms application I have a hierarchy of classes like BaseRecovery
, LoanRecovery
and FineRecovery
. Both LoanRecovery
and FineRecovery
inherits from BaseRecovery
. All these models have one view called RecoveryForm
where you can enter/view loans and fines of employees. and I'm planing to use single Presenter class called RecoveryPresenter
which inherits from BasePresenter
. We have a DataService
Class for db transactions
LoanRecovery class looks like this...
Class LoanRecovery : BaseRecovery
{
public string LoanID {get;set;}
public DateTime IssueDate {get;set;}
public Decimal Amount {get;set;}
.
.
.
}
So I'd do the following in Programe.cs.
IBaseRcovery recovery=null;
IRecoveryForm recoveryForm = new RecoveryForm();
IDataService dataService = new DataService();
BasePresenter presenter = new RecoveryPresenter( recovery, recoveryForm, dataService );
presenter.Show(); // This will display the form recoveryForm
In the presenter I would say
public RecoveryPresenter( IBaseRecover model, IRecoveryForm view, IDataService dataService )
{
this._Model = model;
this._View = view;
this._DataService = dataService;
WireUpViewEvents();
}
Now lets say if I need to give a loan, I would run SetModelPropertisFromView()
method in the BasePresenter
class which use reflection. But before that I should pass an instance of LoanRecovery
class (i.e. _Model) to that method together with _View
. Like wise we can do same thing for all children classes as follows...
public void Issue()
{
if (_View.Type == "Loan")
{
_Model = new LoanRecovery();
SetModelPropertiesFromView(_Model, _View, _DataService);
_dataService.InsertLoan(_Model); //Error
}
if (_View.Type == "Fine")
{
_Model = new FineRecovery();
SetModelPropertiesFromView(_Model, _View, _DataService);
_DataService.InsertFine(_Model); //Error
}
if (_View.Type == "Insurance")
{
_Model = new InsuranceRecovery();
SetModelPropertiesFromView(_Model, _View, _DataService);
_DataService.InsertFine(_Model); //Error
}
}
Everything is fine until the last line of the above if blocks. The issue is the data access method in the DataService
class requires a child instance not a base class instance.
public void InsertLoan( LoanRecovery loan)
{
using (SqlConnection sqlConnection = new SqlConnection(db.GetConnectionString))
{
SqlCommand sqlCommand = new SqlCommand("BEGIN INSERT INTO recovery ;
sqlCommand.Parameters.Add("@empID", SqlDbType.Char).Value = loan.EmployeeID;
sqlCommand.Parameters.Add("@loanType", SqlDbType.VarChar).Value = loan.Type;
sqlCommand.Parameters.Add("@loanAmount", SqlDbType.Decimal).Value = loan.FullAmount;
sqlCommand.Parameters.Add("@loanDuration", SqlDbType.Int).Value = loan.Duration;
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
}
}
So I solved the problem like this
public void Issue()
{
if (_View.Type == "Loan")
{
LoanRecovery loanModel = new LoanRecovery(); //Creates a child instance
SetModelPropertiesFromView(loanModel, _View, _DataService);
_DataService.InsertLoan(loanModel);
}
}
Now it's working but my worry is that I'm not using the injected instance through the constructor rather newing
a child object which creates a dependency. Can anybody propose a better design to solve this issue please?
IBaseRecover
andBaseRecovery
look like? It seems rather confusing that you need different types (i.e.,LoanRecovery
,FineRecovery
, andInsuranceRecovery
) ifIBaseRecover
has all the properties necessary to represent the underlying data, as suggested by the fact that you useIBaseRecover
for your model. \$\endgroup\$