2014-11-12 1 views
1

Это упрощенная версия проблемы, которую я решаю, но концептуально эквивалентна. Этот проект использует виндзорский замок, и я стараюсь держать все заводы в контейнере.Завод для возврата массива IItem из одного объекта

У меня есть единственный объект, представляющий данные, проанализированные из текстового файла. После разбора этого файла мне нужно написать новый текстовый файл с 2 строками на основе данных в исходном объекте.

позволяет сказать текстовый файл Некоторые Person, Рабочий телефон, Мобильный телефон

это получает разобран в

public class Person 
    { 
     public string Name{get;set;} 
     public stirng WorkPhone {get;set;} 
     public stirng MobilPhone {get;set;} 
    } 

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

public interface IFileEntry 
    { 
     string Name{get;set;} 
     string Number{get;set;} 
    } 

    public class PersonWorkPhoneEntry : IFileEntry 
    { 
     public string Name {get;set;} 
     public string Number{get;set;} 
     public override ToString(){....} 
    } 

    public class PersonMobilPhoneEntry: IFileEntry 
    { 
     public string Name{get;set;} 
     public string Number{get;set;} 
     public override ToString(){....} 
    } 

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

public interface IFileEntryFactory 
    { 
     IFileEntry Create(string entryType, stirng Name, string Number 
    } 

Я Создал моя собственная реализация для DefaultTypedFactoryComponentSelector и установите ее только для этой фабрики.

public class FileEntryComponentSelector : DefaultTypedFactoryComponentSelector 
    { 
     protected override string GetComponentName(System.Reflection.MethodInfo method, object[] arguments) 
     { 
      if (method.Name == "Create" && arguments.length == 3) 
      { 
       return (string)arguments[0]; 
      } 

      return base.GetComponentName(method, arguments); 
     } 
    } 

Это работает,

var workEntry = _factory.Create("PersonWorkPhoneEntry", person.Name, person.WorkPhone) 
    var mobilEntry = _factory.Create("PersonMobilPhoneEntry", person.Name, person.WorkPhone) 
    //then write the tostring to a text file 

Извините за длинный установки, но я думаю, что его нужно. То, что я пытаюсь сделать, это

public interface IFileEntryFactory 
    { 
     IFileEntry Create(string entryType, stirng Name, string Number 
     IFileEntry[] Create(Person person) 
    } 

    var entries = _factory.Create(person); 
    foreach(var e in entries) 
    ///write to text file. 

Я искал все решения, подобные этому, без каких-либо результатов. Возможно, что это возможное решение, приведенное здесь (Castle Windsor Typed Factory Facility with generics) В настоящее время я работаю над реализацией чего-то подобного, не уверен, что это правильный способ решить эту проблему.

Вопросов:

  • являются ли какими-либо другими способами, чтобы иметь завод вернуть массив необходимых объектов
  • , что является оптимальным для решения что-то вроде это
  • любых примеров и чтения для передовых заводов

ответ

4

Возможно, что фабрика вернет вам массив объектов, которые уже являются r в контейнере. Вот пример

container.Register(Component.For<IMyStuffProvider>().AsFactory()) // registration 

    public interface IStuffProvider 
    { 
    IEnumerable<IMyStuff> GetAllStuff(); 
    void Release(IMyStuff stuff); 
    } 

Этот код делает возможным, чтобы каждая зарегистрированная реализация IMyStuff была возвращена фабрикой.

Но я думаю, что ваша проблема другая: вы используете завод для неправильной цели. TypedFactory должен получать экземпляры объектов, которые уже зарегистрированы в контейнере во время запуска приложения, а не манипулировать файлами. Их цель - решить проблемы, связанные с зависимостями.

Если вы разбор CSV/TXT в объекты, а затем писать некоторые строки обратно в другой файл CSV/TXT вы должны сделать

  1. IFileEntryManager (с реализацией) с методами, как DeserializeFileToObjects, WriteObjectsToFile и т. д.
  2. IFileEntryManagerFactory для создания и возврата IFileEntryManager. (Замок напечатал завод здесь :))
  3. Теперь добавьте ваш IFileEntryManagerFactory в свой ctor класса, который должен сериализовать/десериализовать текстовые файлы и использовать его для получения вашего FileEntryManager, который, в свою очередь, будет действовать на ваши текстовые файлы.

Если у вас есть разные объекты, такие как Person, Company, Employee ... и т. Д., И вы хотите обрабатывать их с помощью общего манипулятора - все в порядке. Лучший способ - создать общий репозиторий. Допустим, ICsvRepository <T>. Просто найдите «Generic Rpository в C#» и проигнорируйте тот факт, что большинство примеров реализации с EntityFramework являются хранилищем персистентности. За интерфейсом вы можете заставить его читать/записывать в csv, а не в DB.

Позволяет обобщить его. Если вам приходится иметь дело с ресурсами - файлами, sql, blobs, таблицами, шиной сообщений или любым ресурсом, постоянным/непостоянным, который приходит или выходит из вашего приложения, вы должны манипулировать им через абстракцию IMyResourceManager с помощью соответствующих методов манипуляции. Если у вас есть несколько реализаций IMyResourceManager, и вы хотите решить во время исполнения, какую реализацию вы хотите, тогда вы должны сделать IMyResourceManagerFactory с помощью селектора компонентов или фабричного метода и поместить туда свою логику дифференцирования.

Вот почему я думаю, что вам не нужен TypedFactory для чтения/записи текстового файла, но чистый ITextFileManipulator, который вам нужно зарегистрировать в контейнере и получить через конструктор. Вам может понадобиться типичная фабрика, если вы идете на ICsvRepository <T> где T - ваш класс Person. Внутри реализации ICsvRepository <T> вам понадобится ICsvFileManipulator.

+1

спасибо, что нашли время, чтобы написать ответ. очень подробный и полезный. – workabyte