这是我正在解决的问题的简化版本,但概念上相同。 这个项目使用的是温莎城堡,我试图将所有工厂都放在容器中。
我有一个对象,表示从文本文件解析的数据。解析此文件后,我需要根据原始对象中的数据编写一个包含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) 我现在正在努力实现这样的事情,不确定这是否是解决这个问题的正确方法。
问题:
答案 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,则必须进行
如果你有不同的对象,比如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。