I've copy a code from PRISM examples called MVVM RI, within this factory has a Dictionary<Type, Func<Question, QuestionViewModel>>
for mapping. Here it is:
/// <summary>
/// Factory class to create a question view model for a given question object.
/// </summary>
private static class QuestionViewModelFactory
{
private static Dictionary<Type, Func<Question, QuestionViewModel>> maps = new Dictionary<Type, Func<Question, QuestionViewModel>>()
{
{ typeof(OpenQuestion), (q) => new OpenQuestionViewModel((OpenQuestion)q) },
{ typeof(MultipleSelectionQuestion), (q) => new MultipleSelectionQuestionViewModel((MultipleSelectionQuestion)q) },
{ typeof(NumericQuestion), (q) => new NumericQuestionViewModel((NumericQuestion)q) }
};
public static QuestionViewModel GetViewModelForQuestion(Question question)
{
Func<Question, QuestionViewModel> viewModelInstanceFactory = null;
if (maps.TryGetValue(question.GetType(), out viewModelInstanceFactory))
{
return viewModelInstanceFactory(question);
}
else
{
throw new ArgumentOutOfRangeException("Could not locate a view model for question type");
}
}
}
Note that each class derived QuestionViewModel
needs a constructor parameter to be created.
public abstract class QuestionViewModel : NotificationObject
{
protected QuestionViewModel() { ... }
}
public abstract class QuestionViewModel<T> : QuestionViewModel
where T : Question
{
protected QuestionViewModel(T question) { ... }
}
But now, I need to have this factory through discovery (because I don't have a reference, these are in different modules). I was thinking something like create a new custom attribute at the beggining, but then I said: how can I pass the parameter into the constructor?
I'm going to create hundreds of questions of a same data type, that's the reason why [Import]
won't work (I guess).
You could look into using ExportFactory<T>
. This is included in Silverlight and for WPF you can download a port of the Silverlight code from Glenn Block's Skydrive .
With an ExportFactory
you can create as many objects for a given imported type as you like.
[ImportMany]
public IEnumerable<ExportFactory<IModule, IModuleMetadata>> Modules { get; set; }
Then you can call the CreateExport()
method of ExportFactory
to export a fresh object. I recently learned about using ExportFactory
so this post might help you get started.
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.