带有 Unity 容器的 Silverlight 导航框架

发布于 2024-12-15 04:23:40 字数 725 浏览 1 评论 0原文

我正在使用 Silverlight 导航框架,并且最近按照以下一般方式对我的应用程序进行编码:

Public MasterPageView: UserControl
{
    private IMasterPageViewModel _ViewModel = null;

    public MasterPageView():this(new MasterPageViewModel(), new BusinessObjectProvider())
    {
    }

    public MasterPage(IMasterPageViewModel viewModel)
    {
        InitializeComponent();

        _ViewModel = viewModel;
        this.DataContext = viewModel;
    }
}

现在我已经创建了项目的框架,我想在繁重的开发开始之前进行一些整理工作。作为重构过程的一部分,我想利用 Unity IOC 并删除我的默认构造函数。

有人使用过 Silverlight 导航框架和 Unity 吗?如果有任何有关如何解决此问题的建议,我将不胜感激。

我看到的主要问题和问题是 1) 我在Unity框架中哪里注册对象? 2)所有View都是使用Silverlight导航框架中的URIMAPPER创建的,我们如何让URIMAPPER使用Unity创建它的View。

任何帮助将不胜感激。

I'm using the Silverlight Navigation Framework and have recently been coding my appliation in the following general way:

Public MasterPageView: UserControl
{
    private IMasterPageViewModel _ViewModel = null;

    public MasterPageView():this(new MasterPageViewModel(), new BusinessObjectProvider())
    {
    }

    public MasterPage(IMasterPageViewModel viewModel)
    {
        InitializeComponent();

        _ViewModel = viewModel;
        this.DataContext = viewModel;
    }
}

Now that i have the skeleton of my project created, i want to carry out some tidying up, before the heavy development starts. As part of my refactoring process i want to make use of the Unity IOC and take out my Default constructors.

Has anybody used the Silverlight Navigation Framework with Unity? I would appreciate any suggestions on how to go about this.

The Main Problems and questions i see are
1) Where do i register the Objects in the Unity Framework?
2) All Views are created using the URIMAPPER in the Silverlight Navigation Framework, how do we get the URIMAPPER to use Unity to create its Views.

Any help would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

老子叫无熙 2024-12-22 04:23:41

我们在每个页面的 XAML 中使用 Prism 区域。当创建注册到它的视图时,区域将自动执行 IOC 操作。因此,页面不是通过 Unity 创建的,但它们包含的区域是通过 Unity 创建的。

页面中的所有代码所做的就是将任何 Url 参数传递给区域。这是页面所做的一件有点丑陋的事情;他们将查询字符串参数填充到区域的 RegionContext 参数中。然后,该区域的视图中包含一些代码来获取上下文数据并将其传递给 Unity 提供的 VM。

如果您不使用 Prism,这不会有太大帮助。编辑:还有一些关于让 Prism 区域与导航页面良好配合的更多细节。如果你想走这条路,我会分享。

有时,我们确实通过我们创建的静态方法访问统一容器(我认为静态方法只是为您解析对象,它不会为每个人提供整个容器接口)。这很糟糕,但你可以用它手动解决问题。

We use Prism Regions in the XAML of each Page. The regions will automagically do the IOC stuff when it creates the view registered to it. So the Pages don't get created via Unity, but the Regions they contain do.

About all the code in the Pages do is communicate any Url parameters to the Regions. This is a somewhat ugly thing done by the pages; they stuff querystring parmas into the Region's RegionContext param. The View of the region then has some code in it to get that context data and pass it to its Unity provided VM.

If you're not using Prism this won't help much. EDIT: There was some more details on getting Prism regions to work well with navigation Pages. I'll share if you want to go this route.

We do, at times, access the unity container via a static method we created (I think that static method just Resolves objects for you, it doesn't give everyone the entire container interface). It sucks, but you can resolve things manually with that.

怀里藏娇 2024-12-22 04:23:41

看到人们通过 IOC 容器传递视图来创建视图总是让我感到肮脏。您的设计界面(Visual Studio 和 Expression Blend)不会执行此操作 - 它们坚持使用默认构造函数。那么为什么要与他们战斗呢?

一个更简洁的解决方案是使用视图模型定位器模式。这是一个基本的:

public abstract class ViewModelLocator<TViewModel>
{
  public TViewModel ViewModel
  {
    get { return StaticGateway.ServiceLocator.GetInstance<TRuntimeViewModel>(); }
  }
}

其中 StaticGateway 是一个静态类,它提供对 Unity 容器的访问并公开其 ServiceLocator。然后您只需声明一个:

public class MasterPageViewModelLocator : ViewModelLocator<IMasterPageViewModel> { }

并在 XAML 中使用它:

<UserControl x:Class="YourCompany.MasterPageView"  etc.>

  <UserControl.Resources>
    <local:MasterPageViewModelLocator x:Key="Locator" />
  </UserControl.Resources>

  <UserControl.DataContext>
    <Binding Source="{StaticResource Locator}" Path="ViewModel" />
  </UserControl.DataContext>

  ...etc...
</UserControl>

您的绑定通常会更满意,因为您在 XAML 中设置了数据上下文。在代码隐藏中设置数据上下文可能会导致一些奇怪的行为,特别是当您想到诸如附加行为之类的有趣想法时。而且您仍然完全使用 IOC 容器来执行依赖项注入,并且所有设计界面都可以继续发挥作用。

至于在哪里注册,我不确定您将其放在导航应用程序中的确切位置。通常,您将 Unity 与 Prism 之类的工具一起使用,并在模块初始值设定项中执行注册。我想你可以在你的 App 类中做到这一点,或者提出一个与模块初始化程序等效的东西(但是你应该只使用 Prism 而不是重新发明轮子)。

Seeing people create views by passing them through an IOC container always makes me feel dirty. Your design surfaces (Visual Studio and Expression Blend) won't do this -- they insist on a default constructor. So why fight them?

A much cleaner solution is to use the view model locator pattern. Here's a basic one:

public abstract class ViewModelLocator<TViewModel>
{
  public TViewModel ViewModel
  {
    get { return StaticGateway.ServiceLocator.GetInstance<TRuntimeViewModel>(); }
  }
}

Where StaticGateway is a static class that provides access to your unity container and exposes it's ServiceLocator. Then you simply declare one:

public class MasterPageViewModelLocator : ViewModelLocator<IMasterPageViewModel> { }

And use it in XAML:

<UserControl x:Class="YourCompany.MasterPageView"  etc.>

  <UserControl.Resources>
    <local:MasterPageViewModelLocator x:Key="Locator" />
  </UserControl.Resources>

  <UserControl.DataContext>
    <Binding Source="{StaticResource Locator}" Path="ViewModel" />
  </UserControl.DataContext>

  ...etc...
</UserControl>

Your bindings will generally be much happier because you're setting a data context in your XAML. Setting the data context in code behind can lead to some weird behaviors particularly when you get to interesting thinks like attached behaviors. And you're still totally using your IOC container to perform dependency injection with the added benefit of all your design surfaces continue to function.

As for where to register, I'm not sure exactly where you'd put that in a Navigation app. Typically you use Unity with something like Prism and perform the registration in the module initializers. I suppose you could do it in your App class or come up with an equivalent to the module initializer (but then you should just use Prism rather than reinventing the wheel).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文