【问题标题】:IoC - Dynamic Composition of object instancesIoC - 对象实例的动态组合
【发布时间】:2010-06-10 16:08:00
【问题描述】:

有没有办法使用 IoC、MEF [Imports] 或其他 DI 解决方案在对象创建时而不是在组合时动态组合依赖项?

这是我目前的想法。如果您有一个引发事件的对象实例,但您没有创建一次对象并将其保存在内存中,则每次创建对象时都必须注册事件处理程序。据我所知,大多数 IoC 容器都要求您注册组合中使用的所有类并调用 Compose() 以使其连接所有依赖项。

由于对象创建、依赖注入等的开销,我认为这可能是可怕的设计(我在这里处理的是遗留系统)......但我想知道是否可以使用其中之一新兴的 IoC 技术。

也许我混淆了一些术语,但我的目标是避免编写一个框架来“挂钩”对象实例上的所有事件,并使用类似 MEF 的东西来[导出]遵守的处理程序(依赖项)到一个非常特定的接口并将它们 [ImportMany] 导入到一个对象实例中,因此如果应用程序启动时程序集在那里,我的导出会被调用。所以也许所有对象在应用程序启动时仍然可以组合,但我希望系统在创建和销毁对象时找到并调用所有对象。

【问题讨论】:

    标签: .net dependency-injection ioc-container mef


    【解决方案1】:

    在 DI/IoC 环境中处理动态实例化的典型方式是使用抽象工厂。工厂是唯一类允许直接与容器交互的类型,以便在实例化新对象时解决依赖关系。

    public interface IWidgetFactory
    {
        IWidget CreateWidget(...);
    }
    
    public class MyIocWidgetFactory : IWidgetFactory
    {
        private IoCContainer container;
    
        public MyIocWidgetFactory(IoCContainer container)
        {
            if (container == null)
                throw new ArgumentNullException("container");
            this.container = container;
        }
    
        public IWidget CreateWidget(...)
        {
            // Assumes that the container is configured to create transient objects
            // for IWidget, not a singleton.
            return container.Resolve<IWidget>();
        }
    }
    

    请不要将此与服务定位器反模式混淆;没有其他东西可以接触容器,只有工厂,它只创建一种类型的对象。

    此时,您只需将IWidgetFactory 传递给需要在运行时创建小部件的任何内容。就是这样 - 你已经维护了 DI。

    【讨论】:

    • 一些DI容器还支持为你生成工厂。您可以注入例如 Func-delegate。然后 DI 容器为 IWidget 实例生成一个工厂。例如在 Autofac 中:nblumhardt.com/2010/01/the-relationship-zoo
    • 我很好奇,你需要把这个工厂注入到想要创建对象的类中吗?还是需要实例化?
    • @stuartmclark:你注入了工厂。这就是为什么它是 IWidgetFactory 而不是具体类型的原因。有几个 IoC 容器实际上可以自动生成工厂,所以你甚至不需要上面的类型,你只需注入一个 Func&lt;IWidget&gt;Lazy&lt;IWidget&gt;
    • 啊,对,我并不期待创建所有这些工厂!您是否知道 Unity 是否具有此功能?还是我应该看看其他 IoC 容器?谢谢
    • @stuartmclark:我已经很久没有去 Unity 附近了。 Castle Windsor 做得很好,Ninject 有一个扩展;我只能说这两个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 2018-08-18
    相关资源
    最近更新 更多