Implementing the MVVM pattern in C#: How can I create a ViewModel instance, given a Model object whose exact type is only known at runtime?
I have an abstract ModelBase
class and an abstract ViewModelBase
class as well as several derived classes, eg FirstModel : ModelBase
, SecondModel : ModelBase
and so on, as well as FirstViewModel : ViewModelBase
, SecondViewModel : ViewModelBase
etc.
Now I want to implement a function that creates the appropriate view model for a given model object. Something along these lines:
ViewModelBase CreateViewModel(ModelBase someObject)
{
return new ViewModelBase(someObject);
}
The above code does not work of course, because ViewModelBase
is abstract. I rather want to create a new FirstViewModel
, SecondViewModel
and so on depending on the type of someObject
which is only known at runtime.
How would I achieve this?
static Dictionary<Type, Type> TypeMap = new Dictionary<Type, Type>
{
{typeof(ModelA), typeof(ViewModelA)},
{typeof(ModelB), typeof(ViewModelB)},
{typeof(ModelC), typeof(ViewModelC)}
};
static ViewModelBase CreateViewModel(ModelBase someObject)
{
return Activator.CreateInstance(TypeMap[someObject.GetType()]);
}
It wouldn't be wise to allow any model to be coupled with a view model, simply because of type safety. For example, if your view model expects a Movie
, and instead, at run-time, you get a Genre
, how can the view model be expected to behave using this model?
Maybe I'm completely missing your requirements, but you could instead use a generic view model base:
public class ViewModel<TModel> : ViewModelBase
where TModel : ModelBase
{
public TModel Model { get; protected set; }
public ViewModel(TModel model)
{
Model = model;
}
...
}
You can then create your view models based on their mapping . For example:
public class MovieViewModel : ViewModel<Movie>
{
...
}
public class GenreViewModel : ViewModel<Genre>
{
...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.