开发者

Workaround to Prism's RequestNavigate view registration verbosity?

I am using prism view-based navigation with the RequestNavigate method.

The problem I encouner is that I have to register all the ViewModels with the container:

container.RegisterType<object, InboxView>("InboxView");

This is very verbose and requires a list of all the view types I want to register.

Is there any workaround for it?

I think the RequestNavigate should have been generic:

IRegion.RequestNavigate<TView>();

And s开发者_如何学Pythonhould perform the following:

  1. Resolve the view
  2. Give the view a name in the region that should be typeof(TView).Name
  3. Perform the actual navigation request :)
  4. Please vote for my suggestion digest in the Prism issues list.


I see what you are trying to get at, but the proposed solution doesn't really meet with design goals of RegionManager. In particular:

  1. Region requests are type agnostic. If you don't have a reference to a type in Module A from Module B, but want to navigate there, how can can you navigate without these modules referencing each other or having those types refactored into a 3rd assembly?
  2. Regions can have as many views of a particular type as necessary. Your proposed solution would artificially limit the number of views of a particular type to one, which is not currently how regions work.

This doesn't answer your question, though.

As for reducing the verbosity, there isn't much you can do other than roll your own solution that encapsulates the behavior your want in front of RegionManager. Personally I wouldn't go this route, but it's certainly something you could do. You can write this as your own service, or simply an extension method on IRegionManager or IRegion.

public interface IMyNavigationService
{
     //Your own implementation could use (typeof(T)).Name (or 
     //AttributedModelServices.GetContractName(typeof(T)) if using MEF)
     //as the Key, if thatis appropriate for your solution 
     //(1 instance T per region and references to T from all Modules)
     void RequestNavigation<T>();
}

It looks like a switch to MEF as an IoC container might help for your needs... it just depends on which of these lines of code you don't care for. For me, I don't like the RegisterType<object, InboxView>. The MEF equivalent would be:

[Export]
public class InboxView { .. }

You can provide a contract name here ([Export("InboxView")]), but by default it will provide a contract name of AttributedModelServices.GetContractName(typeof(InboxView)). As long as whatever you choose is consistent with how you chose to generate the name in the implementation of IMyNavigationService, it should work fine.

Here is the same thing, but with an extension method implementation (with a MEF implementation... you can choose some other key generation method if you use Unity... you'll just have to add registration of that type in the method as well)

public static class RegionExtensions
{
    public static void RequestNavigate<T>(this IRegion region)
    {
        region.RequestNavigate(AttributedModelServices.GetContractName(typeof(T)));
    }
}

If you are nervous about switching everything to MEF, there is a MefContrib project that makes this much easier... it basically combines Unity and MEF in one.

Hopefully this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜