Стандартный отказ от новичка: я новичок в IoC и получаю смешанные сигналы. Я ищу некоторые рекомендации по следующей ситуации.
Предположим, что у меня есть следующий интерфейс и реализация:
public interface IImageFileGenerator
{
void RenameFiles();
void CopyFiles();
}
public class ImageFileGenerator : IImageFileGenerator
{
private readonly IList<IImageLink> _links;
private readonly string _sourceFolder;
private readonly string _destinationFolder;
private readonly int _folderPrefixLength;
public ImageFileGenerator(IList<IImageLink> links, string sourceFolder, string destinationFolder)
{
_links = links;
_sourceFolder = sourceFolder;
_destinationFolder = destinationFolder;
_folderPrefixLength = 4;
}
public void RenameFiles()
{
// Do stuff, uses all the class fields except destination folder
}
public void CopyFiles()
{
// Do stuff, also uses the class fields
}
}
Я смущаюсь, должен ли я только отправлять интерфейс/зависимости конструктору, создавать некоторый объект параметра и передавать его конструктору или сохранять его как есть и передавать параметры во время разрешения экземпляра.
Итак, есть ли более правильный способ настроить этот код для лучшей работы с контейнером IoC? Можно ли было бы выбрать один из следующих вариантов по моему текущему расположению?
1.
public interface IImageFileGenerator
{
void RenameFiles(IList<IImageLink> links, string sourceFolder);
void CopyFiles(IList<IImageLink> links, string sourceFolder, stringDestFolder);
}
public class ImageFileGenerator : IImageFileGenerator
{
private readonly int _folderPrefixLength;
public ImageFileGenerator()
{
_folderPrefixLength = 4;
}
public void RenameFiles(IList<IImageLink> links, string sourceFolder)
{
// Do stuff
}
public void CopyFiles(IList<IImageLink> links, string sourceFolder, stringDestFolder)
{
// Do stuff
}
}
Мне не нравится, что я передаю то же самое в обоих случаях (кроме папки назначения). В текущей реализации IImageFileGenerator мне нужно выполнить оба метода, и для каждого метода необходимы одинаковые значения. Вот почему я передал состояние через конструктор.
2.
public interface IImageFileGenerator
{
void RenameFiles();
void CopyFiles();
}
public class ImageLinkContext
{
// various properties to hold the values needed in the
// ImageFileGenerator implementation.
}
public class ImageFileGenerator : IImageFileGenerator
{
private readonly IList<IImageLink> _links;
private readonly string _sourceFolder;
private readonly string _destinationFolder;
private readonly int _folderPrefixLength;
public ImageFileGenerator(ImageLinkContext imageLinkContext)
{
// could also use these values directly in the methods
// by adding a single ImageLinkContext field and skip
// creating the other fields
_links = imageLinkContext.ImageLinks;
_sourceFolder = imageLinkContext.Source;
_destinationFolder = imageLinkContext.Destination;
_folderPrefixLength = 4;
}
public void RenameFiles()
{
// Do stuff, uses all the class fields except destination folder
}
public void CopyFiles()
{
// Do stuff, uses all the class fields
}
}
Этот подход может быть даже изменен в Службе фасадов (ранее называемой агрегированными услугами), как упоминается Марк Сееманн здесь.
Я также читал, что вы можете использовать свойства для этих значений и использовать инъекцию свойств, хотя кажется, что это больше не предпочтительнее (autofac упоминает, что встраивание конструктора предпочтительнее... Ninject Я считаю, что даже удалил возможность в версии 2).
В качестве альтернативы я прочитал, что вы также можете создать метод инициализации и убедиться, что свойства там установлены.
Так много вариантов, и я становлюсь более смущенным, когда читаю больше об этом. Я уверен, что нет окончательного правильного пути (или, может быть, есть, по крайней мере, для этого примера???), но, возможно, кто-то может обеспечить плюсы и минусы каждого подхода. Или, может быть, есть другой подход, который я полностью пропустил.
Теперь я понимаю, что этот вопрос, вероятно, немного касается субъективной стороны (и это действительно более одного вопроса), но я надеюсь, что вы можете простить меня и дать некоторые рекомендации.
PS - В настоящее время я пытаюсь использовать автофак в том случае, если это повлияет на дизайн, который лучше подходит.
ПРИМЕЧАНИЕ. Я немного изменил код о целевой папке... он не используется RenameFiles (может иметь отношение к вашему ответу).