Factory从单个对象返回Item的数组

时间:2014-11-12 15:30:30

标签: castle-windsor factory factory-pattern

这是我正在解决的问题的简化版本,但概念上相同。 这个项目使用的是温莎城堡,我试图将所有工厂都放在容器中。

我有一个对象,表示从文本文件解析的数据。解析此文件后,我需要根据原始对象中的数据编写一个包含2行的新文本文件。

让我们说文本文件是 一些人,工作电话,手机

将其解析为

    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(){....}
    }

因此我们正在使用Castle来制作工厂

    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) 我现在正在努力实现这样的事情,不确定这是否是解决这个问题的正确方法。

问题:

  • 有没有其他方法让工厂返回数组 需要的对象
  • 解决类似问题的最佳做法是什么? 这个
  • 高级工厂的任何示例和阅读

1 个答案:

答案 0 :(得分:4)

可以使Factory返回已在容器中注册的对象数组。这是一个例子

  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,而FileEntryManager又会对您的文本文件起作用。
  4. 如果你有不同的对象,比如Person,Company,Employee ......等等,你想用通用操纵器来处理它们 - 没关系。最好的方法是实现Generic Repository。让我们说ICsvRepository&lt; T&gt;。只需在c#&#39;中搜索&#39; Generic Rpository;并忽略大多数实现示例都将EntityFramework作为持久性存储的事实。在界面后面,您可以将其读取/写入csv而不是DB。

    让我们概括一下。如果必须处理资源 - 文件,sql,blob,表,消息总线或任何进入或离开应用程序的持久性/非持久性资源,则必须通过抽象IMyResourceManager及其相应的操作方法对其进行操作。如果你有几个IMyResourceManager实现,并且你想在运行时决定你想要哪个实现,那么你必须使用组件选择器或工厂方法创建IMyResourceManagerFactory并将差异化逻辑放在那里。

    这就是为什么我认为你不需要一个TypedFactory用于文本文件读/写,而是一个纯ITextFileManipulator,你必须在容器中注册并通过构造函数获取它。如果你去ICsvRepository&lt; T&gt;,你可能需要一个打字的工厂。其中T是你的Person类。在ICsvRepository&lt; T&gt;的实现中你需要ICsvFileManipulator。