I have a problem with my MVP structure that is built upon generic presenters, views etc. and I feel I'm violating DRY and I dont know how to get around it.
Example.
public class Presenter<TView, TModel>
where TView : IView
where TModel : Model
{}
So far everything is fine, but I want to have it like this
public class Presenter<TView, TModel>
where TView : IView
where TModel : Model
{}
public class Model<T>
{
public T Value { get;set; }
}
But that won't compile because the where for Model needs a generic parameter. The fix:
public class Presenter<TView, TModel, TModelType>
where TView : IView
where TModel : Model<TModelType>
{}
And it's here I feel i violating dry, take for example
public class MyPresenter : Presenter<IMyView, MyModel, string>
{}
public class MyModel : Model<string>
{}
I feel uncomfortable specifying the string type twice, at the presenter AND at the model, I only wan't to specify that the presenter is using MyModel as Model, I don't care what type of Model (generics). One solution is to remove the generic constraint for the model but then I can't create a generic Model class hierarchy that I want.
Am I thinking wrong about the whole MVP/generics stuff?
In C++, this would be solved with a typedef -- which C# doesn't really have.
public class Model<T>
{
typedef T TModelType; // this doesn't exist in C#
public T Value { get;set; }
}
Then,
public class Presenter<TView, TModel>
where TView : IView
where TModel : Model<TModel::TModelType>
{}
There is a type aliasing that you can do with using
using NewName = any_type<even_generics<with_generics>>
But it's file based -- you can't use it in a class.
I would probably do it like this
Model<T>
to ModelOf<T>
ModelOf<T>
(ModelOf<T> : Model
)where TModel : Model
Model itself will be useful to define the interface methods that don't depend on TModelType.