подача зависимостей в фабричный класс через IoC? - PullRequest
4 голосов
/ 16 февраля 2010

У меня есть фабричный класс, который решает, какой из четырех доступных подклассов он должен создать и вернуть. Как и следовало ожидать, все подклассы реализуют один и тот же интерфейс:

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!");
            }
     }
}

Как видите, один из подклассов имеет зависимость, определенную в его конструкторе.

Некоторые достопримечательности:

  • Мы используем Spring.NET в качестве IoC.
  • Все подклассы IFoo являются объектами домена и, следовательно, не создаются в Spring.NET. Я бы хотел, чтобы все было так, если это вообще возможно.
  • Приложение имеет рукописный уровень доступа к данным (puke), поэтому ORM здесь не используется.

Я пытаюсь выяснить, как лучше всего передать зависимость IBar в Foo3 из FooFactory. У меня такое ощущение, что эту проблему лучше всего решить с помощью IoC, но я не могу понять, как это сделать. Я также хочу, чтобы FooFactory был как можно более тестируемым модулем: т.е. я бы предпочел, чтобы в моем тестовом коде не было зависимостей от Spring.NET.

Спасибо за чтение.

Ответы [ 2 ]

6 голосов
/ 16 февраля 2010

Измените FooFactory на Abstract Factory и внедрите экземпляр 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 interface IFooFactory
{
    IFoo CreateFoo(FooEnum emum);
}

Везде в вашем коде, где вам нужен экземпляр IFoo, вы возьмете зависимость от IFooFactory и будете использовать его метод CreateFoo для создания нужного вам экземпляра.

Вы можете подключить FooFactory и его зависимости, используя любой DI-контейнер, достойный его внимания.

0 голосов
/ 16 февраля 2010

звучит так, как будто ты хочешь свой торт и съесть его тоже. Вы должны придерживаться своей стратегии МОК.

вы наберете мо бетта-код, и цыпочки тоже будут вас копать ....; p

...