Configuration 通过IoC将依赖项馈送到工厂类?

Configuration 通过IoC将依赖项馈送到工厂类?,configuration,inversion-of-control,factory,spring.net,Configuration,Inversion Of Control,Factory,Spring.net,我有一个工厂类,它决定应该实例化并返回四个可用子类中的哪一个。正如您所期望的,所有子类都实现相同的接口: public static class FooFactory{ public IFoo CreateFoo(FooEnum enum){ switch (enum) { case Foo1: return new Foo1(); c

我有一个工厂类,它决定应该实例化并返回四个可用子类中的哪一个。正如您所期望的,所有子类都实现相同的接口:

public static class FooFactory{
     public IFoo CreateFoo(FooEnum enum){
            switch (enum)
            {
                case Foo1:
                    return new Foo1();
                case Foo2:
                    return new Foo2();
                 case Foo3:
                    return new Foo3(IBar);//has a constructor dependency on IBar
                case Foo4:
                    return new Foo4();
                 default:
                    throw new Exception("invalid foo!");
            }
     }
}
public interface IFooFactory
{
    IFoo CreateFoo(FooEnum emum);
}
如您所见,其中一个子类在其构造函数中定义了依赖项

一些关注点:

  • 我们正在使用Spring.NET作为我们的IoC
  • IFoo
    的所有子类都是域对象,因此没有被Spring.NET实例化。如果可能的话,我想保持这种状态
  • 该应用程序有一个手写数据访问层(puke),因此这里没有ORM
我试图找出如何最好地将
IBar
依赖项从
FooFactory
传递到
Foo3
。我觉得这可能是一个最好通过国际奥委会解决的问题,但我不知道如何解决。我还希望尽可能保持
FooFactory
的单元可测试性:也就是说,我希望在测试代码中不必依赖Spring.NET


感谢阅读。

将FooFactory更改为抽象工厂,并将IBar实例注入到具体实现中,如下所示:

public class FooFactory : IFooFactory {
     private readonly IBar bar;

     public FooFactory(IBar bar)
     {
         if (bar == null)
         {
             throw new ArgumentNullException("bar");
         }

         this.bar = bar;
     }

     public IFoo CreateFoo(FooEnum enum){
            switch (enum)
            {
                case Foo1:
                    return new Foo1();
                case Foo2:
                    return new Foo2();
                 case Foo3:
                    return new Foo3(this.bar);
                case Foo4:
                    return new Foo4();
                 default:
                    throw new Exception("invalid foo!");
            }
     }
}
请注意,FooFactory现在是一个具体的非静态类,实现了IFooFactory接口:

public static class FooFactory{
     public IFoo CreateFoo(FooEnum enum){
            switch (enum)
            {
                case Foo1:
                    return new Foo1();
                case Foo2:
                    return new Foo2();
                 case Foo3:
                    return new Foo3(IBar);//has a constructor dependency on IBar
                case Foo4:
                    return new Foo4();
                 default:
                    throw new Exception("invalid foo!");
            }
     }
}
public interface IFooFactory
{
    IFoo CreateFoo(FooEnum emum);
}
在代码中需要IFoo实例的任何地方,都将依赖IFooFactory并使用其CreateFoo方法创建所需的实例


你可以使用任何值得一试的DI容器来连接FooFactory及其依赖关系。

听起来你既想要蛋糕,也想吃蛋糕。你需要致力于你的国际奥委会战略


你将产生一个mo和betta代码,小鸡们也会更喜欢你;p

@Sky Sanders,我不知道你和哪个小妞在一起,但根据我的经验,如果你致力于一项IoC战略,他们中的任何一个都不会对你产生更大的影响。你不必在最近一刻才致力于一个特定的DI容器:我的部分问题是找出工厂和控制模式反转在依赖注入连续体中的位置。也许你能提供一个更具启发性的回答?@dirk:等一下,我有一些东西要学……我承认,我的回答有点不着边际,但这正是我所想的。。。让我仔细看看马克的回答。@sam:老兄,小妞们喜欢承诺。问一个问题好的,我明白你的策略,而且我也支持我所说的。我错过什么了吗?我不是建议什么时候实施IOC,只是他不需要避免在他的工厂里使用IOC+1如果粘贴一些有效代码;-)@Sky Sanders:最好避免在工厂内使用DI容器。工厂和其他任何东西一样是一个域对象,将容器放在域对象中会导致服务定位器反模式:哦,我已经这样做了:@Mark:为什么要使用抽象工厂而不是使用带有静态Create()方法的非派生类?我不打算让这家工厂有一次以上的实施。如果需要的话,我可以使用重新分解工具来提取接口。一般来说,静态工厂只是具有另一个名称的单例,它们有很多问题:静态工厂不能很好地分离关注点,您可能会在代码中使用它作为“虚拟新操作员”。这再一次削弱了类耦合。它与服务定位器反模式有着相同的问题:我认为bob叔叔有一篇关于这个主题的臭名昭著的帖子。