Иерархия зависимостей интерфейса - PullRequest
1 голос
/ 05 февраля 2012

В настоящее время у меня есть основной класс, который может вызывать другой класс, который может вызывать 2 или 3 других.Основной класс также может создавать форму Windows.

Так что на данный момент мы можем иметь:

public class MainClass
{
  ...
  AnotherClass = new AnotherClass();
  fmMain myForm = new fmMain();
}

public class AnotherClass
{
  ...
  DatabaseClass dbClass = new DatabaseClass();
  FileClass fClass = new FileClass();
}

Как я вижу, после рефакторинга и добавления зависимостей интерфейса конструктора я могу использоватьконтейнер IOC.

Проблема в том, что моя точка входа - это основной класс, поэтому все, что я могу видеть, это иметь все зависимости в конструкторе основного класса и затем передавать их в другие классы и формы.

Проблема в том, что это может стать очень запутанным, и у основного класса может быть 10 зависимостей, большинство из которых используются в других классах.Есть ли альтернатива?

Ответы [ 3 ]

5 голосов
/ 05 февраля 2012

Позвольте контейнеру IoC сделать это.

Зарегистрируйте AnotherClass как зависимость, а затем разрешите ее, обращаясь непосредственно к экземпляру контейнера.

2 голосов
/ 05 февраля 2012

Зависимости должны быть определены локально там, где они требуются, т.е. зависимости должны быть определены от конструкторов типов, а затем использовать контейнер IoC для разрешения всех типов.Таким образом, IoC заботится о «передаче их в другие классы и формы».При использовании контейнера IoC по возможности избегайте использования «new», а вместо этого используйте контейнер для создания экземпляров.Он будет обрабатывать создание и внедрение зависимостей для вас.

Например (с использованием Ninject), следующий пример демонстрирует Form, который определяет свои собственные зависимости.Контейнер будет предоставлять и вставлять все зависимости рекурсивно при использовании для разрешения экземпляра ProductForm.

Зависимости не нужно вводить в класс точки входа, но они указаныкак привязки в модуле, а затем внедряются контейнером при разрешении таких типов, как Forms.

public class Program
{
    public Program()
    {
        IKernel kernel = new StandardKernel(new MainModule());

        Form form = kernel.Get<ProductForm>();

        form.Show();
    }
}

public class MainModule : NinjectModule
{
    public override void Load()
    {
        Bind<ProductForm>().ToSelf();
        Bind<IProductService>().To<ProductService>();
        Bind<IProductDb>().To<IProductDb>();
    }
}

internal class ProductForm : Form
{
    private readonly IProductService _productService;

    public ProductForm(IProductService productService)
    {
        _productService = productService;
    }
}

internal interface IProductService {}

internal class ProductService : IProductService
{
    private readonly IProductDb _productDb;

    public ProductService(IProductDb productDb)
    {
        _productDb = productDb;
    }
}

internal interface IProductDb {}

internal class ProductDb : IProductDb {}
0 голосов
/ 05 февраля 2012

Звучит так, будто ваш Основной класс - это ваш Корень композиции . Это нормально - это не станет грязным, если это то, что делает only . Это должно быть его единственной ответственностью. Другими словами: точка входа вашего приложения должна быть Humble Object .

...