【问题标题】:IoC - Constructor takes a runtime value as one parameter and a service as anotherIoC - 构造函数将运行时值作为一个参数,将服务作为另一个参数
【发布时间】:2011-03-22 21:12:28
【问题描述】:

我有一个 WPF 应用程序,它在启动时会查看文件系统中的一些配置文件

对于它找到的每个配置文件,它会在不同的窗口中显示一些信息

每个窗口都有一个关联的 ViewModel 对象,该对象绑定到窗口数据上下文

因此为每个配置文件创建了一个新的 ViewModel。代表配置文件中数据的对象被传递到 viewmodels 构造函数中

然而,视图模型也有其他依赖传递给构造函数

代码看起来像这样(在从 app.xaml 启动的引导程序中)

foreach (WindowConfig config in ConfigManager.GetConfigs())
{
    IMyService svc = new MyService();

    //change to resolve from IoC container
    MyViewModel vm = new MyViewModel(config, svc);

    Window1 view = new Window1();

    view.DataContext = vm;

    window.show();
}

我想使用 Castle IoC 容器解决这些依赖关系。我知道如何为 IMyService 执行此操作,但是如何为从配置文件创建的特定类执行此操作?

谢谢

【问题讨论】:

    标签: c# wpf dependency-injection ioc-container castle


    【解决方案1】:

    永远记住,在应用程序代码中,从容器中提取永远不是解决方案。 应用程序代码应该不知道有一个 DI 容器在运行

    The general solution when you need to resolve a dependency based on a run-time value is to use an Abstract Factory.

    在您的情况下,工厂可能如下所示(假设您的 config 变量是字符串:

    public interface IViewModelFactory
    {
        IViewModel Create(string configuration);
    }
    

    现在您可以将 IViewModelFactory 作为单个依赖项注入到循环通过配置文件的类中。

    要实现 IViewModelFactory,您可以手动实现,也可以使用 Castle Windsor 的 Typed Factory Facility 为您实现。

    【讨论】:

    • 嗯...不太明白这个。这不只是给问题增加了一层抽象吗?我仍然需要将参数传递给 create 方法,但还需要从容器中解析一个。任何机会你可以解释一下......我的工厂看起来像这样: public interface IViewModelFactory { IViewModel Create(WindowConfig configuration, IMyService svc);
    • 另外,这一切都发生在我的引导课程中。这是我第一次碰到容器的地方。因此,将依赖项传递给它意味着容器不会解决它......正如你可能会说的那样,我有点困惑
    • 我看到你之前已经回答过几次这个问题了——这是最终让我明白的解释......谢谢stackoverflow.com/questions/1926826/cant-combine-factory-di
    【解决方案2】:

    您可以通过使用将IDictionary 作为参数的IWindsorContainer.Resolve 的重载将参数传递给Windsor,它应该在解析构造函数时使用该参数。在这个字典中,key应该是参数名,value应该是作为参数值使用的对象:

    var arguments = new Dictionary<string,object> {{ "config", config }, { "service", svc } };
    var viewModel = container.Resolve<MyViewModel>(arguments);
    

    【讨论】:

    • 是否可以从容器中解析 IMyService 的具体类型(即在 Windsor XML 或 Fluent 接口中指定)。并且只在字典中传递了配置参数?也许我需要更改它,以便通过参数注入而不是构造函数注入传递配置? (虽然我不希望这样做)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    相关资源
    最近更新 更多