2012-04-29 78 views
14

我正在研究一个中等规模的WPF应用程序(MVVM),这个应用程序在将来应该是可扩展和可维护的。因此我决定使用一个IoC容器(在这种情况下是Unity)来保持灵活性。何处放置和配置WPF应用程序中的IoC容器?

但是我不确定在WPF应用程序中放置和配置Unity的位置。

我想容器应该可以全局访问,所以它应该可能去应用程序类。但是,我应该把它作为静态属性吗?我应该在Application_Startup()事件处理程序中配置它吗?

如:

/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application 
{ 
    public static UnityContainer MyUnityContainer; 


    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     // instantiate and configure Unity 
    } 
} 

这样我就可以通过静态属性,从任何地方访问容器中的应用:

App.MyUnityContainer 

我想这是一个办法做到这一点,但我我不确定这个问题是否有更好的做法,特别是WPF应用程序。

回答

8

看看Composition Root Pattern。你想要做的是在你的Startup事件处理程序中初始化它,并忘记它在应用程序的其余部分的存在。

您正在尝试执行Service Locator Pattern,根据许多is an inferior solution来解决此问题。

+0

我怎样才能完全忘记它的存在?你会想解决你的依赖关系图最高层的依赖关系,不是吗?我的意思是,例如,按钮点击事件处理程序应该将“Customer”保存到使用“CustomerRepository”的数据库。你不需要为了使用它而解决'CustomerRepository',因此再次需要IoC容器吗? – 2012-10-15 21:10:07

+1

@JoaoMilasch最高层?绝对。但为什么最顶层是一个窗口而不是App类?在你的情况下,你有一个窗口需要一个存储库,可以通过构造函数注入注入。然后,您可以在调用容器的App的Startup事件中解析MainWindow。 – 2012-10-16 07:27:43

+0

啊哈!你间接回答了我的问题,现在这一切都很有意义。我想我需要在App类上配置容器,但Windows需要直接访问配置的容器。相反,如果我按照你的建议去做,容器对象只需要存在于App类中。请纠正我,如果我错了,请! :) 谢谢! – 2012-10-16 11:36:55

5

让我发布我所得出的结论,希望它能帮助人们。纠正是否有什么问题! :P

我想我们会寻找到这样的事情:

/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application 
{ 
    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     UnityContainer myUnityContainer = new UnityContainer(); 
     //make sure your container is configured 
     myUnityContainer.RegisterType<ISomeDependency, SomeDependencyImplementation>(); 
     myUnityContainer.RegisterType<IMainWindow, MainWindow>(); 

     myUnityContainer.Resolve<IMainWindow>().Show(); 
    } 
} 

public partial class MainWindow : Window, IMainWindow 
{ 
    private ISomeDependency _someDependency; 

    public MainWindow(ISomeDependency someDependency) 
    { 
     _someDependency = someDependency; 
    } 
} 

注意有没有全局变量或单身,容器,只要主窗口确实和这背后切入点所有依赖进一步后生还只要容器知道它们,就会自动解析到合成图中。

+1

我想你想要RegisterType而不是Register。 – 2014-05-07 21:40:05

+0

感谢您的更正@JacobBrewer – 2014-05-08 19:33:14

+1

@JoaoMilasch错过了一个部分,并且(对我来说不清楚)容器是如何被“提升”成为主容器的,这与你在asp.net MVC中通过“GlobalConfiguration.Configuration .DependencyResolver”。仅当容器中的所有依赖项都有引用时,“解析”才会检查。 – stenly 2014-09-15 03:12:46

1

根据Unity容器的新版本,我们还必须注册它自己的实例,以便通过构造函数注入将其获取到视图模型中。

App.xaml.cs文件:

protected override void OnStartup(StartupEventArgs e) 
{ 
     var unityIoC = new UnityContainer(); 
     unityIoC.RegisterTypes(AllClasses.FromAssembliesInBasePath(), WithMappings.FromMatchingInterface, WithName.Default); 
     unityIoC.RegisterInstance(typeof(IUnityContainer), unityIoC); 
} 

视图模型类

[InjectionConstructor] 
public MyViewModel(IUnityContainer container) 
{ 
} 

现在团结容器将在视图模型为我们提供,可用于解决。

相关问题