Reputation: 8462
I want to make some things the most generic possible. Shortly, I've 2 documents to print :
ThirdParty
So what I've so far is :
#region Models
public abstract class ThirdParty
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Student : ThirdParty
{ public DateTime Birthday { get; set; } }
public class Worker : ThirdParty
{ public string Company { get; set; } }
#endregion
#region ViewModels
public abstract class BaseViewModel<T> where T : ThirdParty
{
public T Model { get; set; }
public DateTime SelectedDate { get; set; }
public CultureInfo SelectedCulture { get; set; }
}
public class StudentViewModel : BaseViewModel<Student>
{ public string SchoolInput { get; set; } }
public class WorkerViewModel : BaseViewModel<Worker>
{ public string JobInput { get; set; } }
#endregion
#region Document
public abstract class Document<T>
where T : BaseDocumentViewModel
{
public string Template { get; protected set; }
public string FileName { get; protected set; }
public T DocumentViewModel { get; protected set; }
}
public class StudentDocument : Document<StudentDocumentViewModel>
{
public StudentDocument()
{
Template = "student.docx";
FileName = $"{DocumentViewModel.BaseViewModel.Model.FirstName} {DocumentViewModel.BaseViewModel.Model.LastName}";
}
}
public class WorkerDocument : Document<WorkerDocumentViewModel>
{
public WorkerDocument()
{
Template = "worker.docx";
}
}
#endregion
#region Document ViewModels
public abstract class BaseDocumentViewModel
{
public BaseViewModel<ThirdParty> BaseViewModel { get; set; }
public string PrintingDate { get { return BaseViewModel.SelectedDate.ToString(BaseViewModel.SelectedCulture.DateTimeFormat.ShortDatePattern); } }
}
public class StudentDocumentViewModel : BaseDocumentViewModel
{
public StudentViewModel StudentViewModel { get; set; }
public int Age { get { return DateTime.Now.Year - StudentViewModel.Model.Birthday.Year; } }
}
public class WorkerDocumentViewModel : BaseDocumentViewModel
{
public WorkerViewModel WorkerViewModel { get; set; }
public string Position { get { return $"{WorkerViewModel.Model.Company} - ${WorkerViewModel.JobInput}"; } }
}
#endregion
Is it possible to simplify the BaseDocumentViewModel
to make it more generic ? Needing to describe the BaseViewModel
to one property and the specialized one one in another doesn't look that great.
Something like :
public abstract class BaseDocumentViewModel // What to put here ?
{
public T ViewModel { get; set; }
public string PrintingDate { get { return ViewModel.SelectedDate.ToString(ViewModel.SelectedCulture.DateTimeFormat.ShortDatePattern); } }
}
// How to describe the subclasses ?
Any hint is welcome.
Upvotes: 0
Views: 70
Reputation: 5791
You need an interface with a covariant generic parameter.
For example IThirdPartyViewModel<out T>
.
Something like this:
// Entities
public abstract class ThirdParty
{
}
public class Student : ThirdParty
{
}
public class Worker : ThirdParty
{
}
// View models
public interface IThirdPartyViewModel<out T>
{
}
public abstract class ThirdPartyViewModel<T> : IThirdPartyViewModel<T>
{
}
public class StudentVm : ThirdPartyViewModel<Student>
{
}
public class WorkerVm : ThirdPartyViewModel<Worker>
{
}
public abstract class DocumentViewModel<T> where T : IThirdPartyViewModel<ThirdParty>
{
}
public class StudentDocumentVm : DocumentViewModel<StudentVm>
{
}
public class WorkerDocumentVm : DocumentViewModel<WorkerVm>
{
}
Upvotes: 1