简体   繁体   中英

How to implement this viewmodel factory using MEF?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM