【发布时间】:2012-01-19 18:50:12
【问题描述】:
我正在处理与此非常相似的遗留代码:
public class BaseParser
{
public BaseParser(Stream stream)
{
// Do something with stream
}
}
public class JsonParser : BaseParser
{
public JsonParser(Stream stream)
: base(stream)
{
// Do something
}
}
public class XmlParser : BaseParser
{
public XmlParser(Stream stream, string someOtherParam)
: base(stream)
{
// Do something
}
}
我们有一个使用特定解析器解析传入文件的应用程序。为了确定我们需要实例化哪种类型,工厂方法中有一个大的 IF/ELSE 块:
public static BaseParser Create(string type)
{
if (type == "xml")
return new XmlParser(new FileStream("path", FileMode.Open), "test");
if (type == "json")
return new JsonParser(new FileStream("path", FileMode.Open));
// more...
return null;
}
由于有大量解析器驻留在单个程序集中(我们称之为Demo.dll),我想将这些解析器中的每一个拆分为它们自己的程序集。诸如BaseParser 之类的“核心”类将保留在Demo.dll 中,但其他解析器和任何依赖项将存在于Demo.Json.dll、Demo.Xml.dll 等中......
“核心”库将在运行时加载这些程序集。
string[] paths = Directory.GetFiles(Environment.CurrentDirectory, "Demo.*.dll");
foreach (string path in paths)
Assembly.LoadFrom(path);
List<BaseParser> parsers = AppDomain.CurrentDomain
.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(x => x.IsSubclassOf(typeof(BaseParser)))
.Select(x => (BaseParser) Activator.CreateInstance(x))
.ToList();
问题从这里开始。上面的代码将不起作用,因为每个遗留解析器都没有无参数构造函数。另外,我想不出替换 IF/ELSE 块并让每个解析器确定它可以处理哪个文件的好方法。我正在考虑可能在基本解析器上添加一个虚拟方法:
public virtual bool ShouldHandle(string type)
{
return false;
}
... 每个派生的解析器都会覆盖这个虚拟方法。但是,有两个问题:
没有无参数构造函数,每个类的构造函数可以有不同数量的参数。这不是我可以改变的,因为这些遗留类无处不在。
我必须先实例化类,然后才能调用
ShouldHandle方法。这给在构造函数中从流中读取的类带来了问题。
我可以采取其他方法将这些解析器拆分为它们自己的程序集吗?
编辑:
这是一个 .NET 3.5 应用程序。遗憾的是没有 MEF。
【问题讨论】:
标签: c# design-patterns refactoring