tags:

views:

66

answers:

1

Hi,

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?

+2  A: 

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

  1. rename Model<T> to ModelOf<T>
  2. Make a Model base class for ModelOf<T> (ModelOf<T> : Model)
  3. Use where TModel : Model

Model itself will be useful to define the interface methods that don't depend on TModelType.

Lou Franco
Nice, but instead of base Model i defined a IModel interface.
Marcus