Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
478 views
in Technique[技术] by (71.8m points)

c# - prism:ViewModelLocator.AutoWireViewModel="True" will not work for not referenced assemblies

I load my modules in the bootstrapper with:

    protected override IModuleCatalog CreateModuleCatalog()
    {
        var moduleCatalog = new DirectoryModuleCatalog();
        moduleCatalog.ModulePath = @".Modules";
        return moduleCatalog;
    }

which works fine when the project of the modules are referenced in the shell project. The correct ViewModels will be injected by the following attached property.

<UserControl prism:ViewModelLocator.AutoWireViewModel="True" [..]</>

Unless I remove the project reference the ViewModels will not be set anymore by the prism:ViewModelLocator.AutoWireViewModel="True".

Does anybody know the what causes that? You can watch this behaviour on the project https://github.com/mfe-/Get.the.solution.Prism.Demo . How can I fix this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Basically, when the ViewModelLocationProvider calls the _defaultViewTypeToViewModelTypeResolver, the call to Type.GetType(string) returns null.

This might be related to how MEF loads assemblies in general. This seems to be a common probem with MEF and a Google search will return a lot of results with similar issues. Here is someone with the same problem:

Type.GetType returns null when using MEF

You could try adding the plugin location in the probing path of the application.

I personally never use MEF as a DI container, because it's not one. But that is a conversation for another day.

EDIT: Actually, I just thought of a better way to get around this. Simply override ConfigureViewModelLocator in your bootstrapper like this:

        protected override void ConfigureViewModelLocator()
    {
        base.ConfigureViewModelLocator();

        ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(viewType =>
        {
            var viewName = viewType.FullName;
            viewName = viewName.Replace(".Views.", ".ViewModels.");
            var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
            var suffix = viewName.EndsWith("View") ? "Model" : "ViewModel";
            var viewModelName = String.Format(CultureInfo.InvariantCulture, "{0}{1}", viewName, suffix);

            var assembly = viewType.GetTypeInfo().Assembly;
            var type = assembly.GetType(viewModelName, true);

            return type;
        });
    }

This way we can ask the assembly for the type directly and not try to have the framework figure it out for us.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...