Назначение свойств на зависимости класса - PullRequest
0 голосов
/ 22 марта 2012

Допустим, у меня есть класс, который принимает IFileLogger в качестве аргумента конструктора.

public MyClass : IClass
{
    private IFileLogger Logger;
    public MyClass(IFileLogger Logger)
    {
        this.Logger = Logger;
    }
}

Где-то в этом классе это вызывает Logger.Write("Data");

IFileLogger имеет свойство DirectoryPath;

Это нужно установить так, чтобы IFileLogger знал, куда записать файл.

Как это установить?

Я думаю, что свойство класса должно быть установлено, а затем в конструкторе есть что-то вроде IFileLogger.DirectoryPath = this.DirectoryPath.

Это кажется неправильным, поскольку IClass должен иметь свойство, и в итоге вы создаете цепочку свойств, которые нужны только на нижнем уровне.

Можете ли вы помочь кому-то, кто не видит дерево за деревьями? Также, вы бы написали тесты и как определить, что IFileLogger заполнил его DirectoryPath?

Ответы [ 3 ]

0 голосов
/ 22 марта 2012

Как правило, я бы сказал, что ваш объект должен быть готов к использованию после его создания, и необходимость вызывать другие методы / свойства для его подготовки просто сбивает с толку.Поэтому у Logger уже должно быть установлено свойство DirectoryPath перед передачей его в MyClass.Например:

SomeInitialisationMethod
    ()
{
    // or use IOC "factory" to create necessary concrete version.
    IFileLogger logger = new LoggerVariant("path");

    // MyClass can now use the ready to use logger. If we need to set the DirectoryPath, we can do it on this calling stack through the logger. 
    MyClass myClass = new MyClass(logger);
0 голосов
/ 22 марта 2012

Могу ли я предположить, что проблема заключается в дизайне вашего интерфейса, а ваш вопрос - в запахе?

IFileLogger представляет интерфейс, от которого зависит ваш класс. Таким образом, глядя на интерфейс, мы видим, что существует метод Write. Дело в том, что MyClass на самом деле не волнует, как происходит регистрация, только то, что она соответствует интерфейсу. С учетом сказанного, мысль о том, что MyClass необходимо знать местоположение каталога, чтобы сообщить IFileLogger, как выполнять свою работу, говорит о том, что ответственность неуместна.

Какой код нужен IFileLogger? Вход, верно? Давайте немного переработаем код и реализуем интерфейс для нужд клиента, MyClass. Ему все равно, как происходит регистрация, просто что произойдет .

Вместо этого переименуйте интерфейс на ILogger.

public MyClass : IClass
{
    private ILogger Logger;
    public MyClass(ILogger Logger)
    {
        this.Logger = Logger;
    }
}

Теперь, когда в этом классе нет ссылок на «Файл», становится более очевидным, что параметр каталога здесь не принадлежит. Куда это относится? Вероятно, в самом FileLogger.

Использование Dependency Injection позволит вам получить что-то вроде:

main() {
  // Poor man's DI, no frameworks here
  var logger = new FileLogger("some/directory");
  var instance = new MyClass(logger);
  return instance.DoSomethingUsefulThatEventuallyGetsLogged();
}

Надеюсь, это поможет!

Brandon

0 голосов
/ 22 марта 2012

Как и где вы создаете экземпляр IFileLogger, кажется, это место для установки его свойства.

  builder.RegisterType<FileLogger>().WithParameter(new NamedParameter("directoryPath", @"c:\temp")).As<IFileLogger>();

С этой конфигурацией, каждый раз, когда вы будете использовать этот конструктор для разрешения IFileLogger, он будет использовать «c: \ Temp» в качестве directoryPath.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...