gpt4 book ai didi

.net - 依赖注入(inject)和 Fluent APIs——遇到了一些问题

转载 作者:行者123 更新时间:2023-12-01 11:05:39 25 4
gpt4 key购买 nike

我正在编写一个流畅的界面,使用方式如下:

xmlBuilder
.CreateFrom()
.DataSet(someDataSet) //yes I said Dataset, I'm working with a legacy code
.IgnoreSchema()
.Build

IgnoreSchema() 方法可以用 WithSchema()WithDiffGrame() 代替。这些映射到接受以下枚举的 DataSet 的 WriteXml() 方法:

  • XmlWriteMode.WriteSchema
  • XmlWriteMode.DiffGram
  • XmlWriteMode.IgnoreSchema

我的 Fluent API 正在调用某种工厂对象,它将根据数据集创建 XML。我有一个具有核心功能的抽象类型,然后是 3 个派生类型,它们反射(reflect)了实现 WriteXmlFromDataSet 方法的各种状态(我相信这种方法称为状态模式)。这是抽象基类:

public abstract class DataSetXmlBaseFactory : IDataSetXmlFactory
{
...

protected abstract void WriteXmlFromDataSet(XmlTextWriter xmlTextWriter);

public XmlDocument CreateXmlDocument()
{
XmlDocument document = new XmlDocument();
using (StringWriter stringWriter = new StringWriter())
{
using (XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter))
{
WriteXmlFromDataSet(xmlTextWriter);
string content = stringWriter.ToString();
document.LoadXml(content);
return document;
}
}
}
}

这当然有效,但是当我将这段代码与依赖注入(inject)一起使用时,我遇到了开头提到的流畅界面中的方法的麻烦。以下是这些方法的实现:

public IXmlBuild<T> WithSchema()
{
var xmlFactory = new DataSetXmlWithSchemaFactory(this.DataSet);
return GetIXmlBuild(xmlFactory);
}
public IXmlBuild<T> IgnoreSchema()
{
var xmlFactory = new DataSetXmlIgnoreSchemaFactory(this.DataSet);
return GetIXmlBuild(xmlFactory);
}
public IXmlBuild<T> WithSchemaAndDiffGram()
{
var xmlFactory = new DataSetXmlWithDiffGramFactory(this.DataSet);
return GetIXmlBuild(xmlFactory);
}
private static IXmlBuild<T> GetIXmlBuild(IDataSetXmlFactory xmlFactory)
{
string content = xmlFactory.CreateXmlDocument().InnerXml;
return new clsXmlDataSetBuild<T>(content);
}

现在我没有使用依赖注入(inject) (DI),因为我正在更新相关的 IDataSetXMLFactory 对象。如果我更改代码以利用 DI,该类如何知道要使用 IDataSetXmlFactory 的哪个实现?如果我正确理解 DI,则需要在调用堆栈的更高层(特别是在 Composition Root)做出该决定,但那里的代码不知道需要哪个确切的实现。如果我在上述方法中使用 DI 容器来解析(定位)所需的实现,那么我将使用 DI 容器作为服务定位器,这被​​认为是一种反模式。

此时,将枚举传递给 IXmlDataSetFactory 实例上的 xmlFactory.CreateXmlDocument() 方法会容易得多。这当然更容易,代码也更少,但我确信这个问题以前在状态模式和 DI 中遇到过。有什么方法可以解决这个问题?我是 DI 的新手,已经开始阅读 Dependency Injection in .NET ,但尚未阅读有关此特定问题的任何内容。

希望我只是遗漏了一小块拼图。


更新 (基于 Mark Seemann 的回答)

下面界面的语义模型是什么样的?示例将不胜感激。

public interface IXmlBuilder<T>
{
IXmlSourceContent<T> CreateFrom();
}

public interface IXmlSourceContent<T>
{
IXmlOptions<T> Object(T item);
IXmlOptions<T> Objects(IEnumerable<T> items);
IXmlDataSetOptions<T> DataSet(T ds);
IXmlBuild<T> InferredSchema();
}

public interface IXmlOptions<T> : IXmlBuild<T>
{
IXmlBuild<T> WithInferredSchema();
}

public interface IXmlDataSetOptions<T> : IXmlDataSetSchema<T>
{
IXmlDataSetSchema<T> IncludeTables(DataTableCollection tables);
IXmlDataSetSchema<T> IncludeTable(DataTable table);
}

public interface IXmlBuild<T>
{
XmlDocument Build();
}

public interface IXmlDataSetSchema<T>
{
IXmlBuild<T> WithSchemaAndDiffGram();
IXmlBuild<T> WithSchema();
IXmlBuild<T> IgnoreSchema();
}

除了上面提到的IDataSetXMLFactory,我还有以下扩展方法:

static class XmlDocumentExtensions
{
[Extension()]
public static void InsertSchema(XmlDocument document, XmlSchema schema)
{
...
}
}

static class XmlSchemaExtensions
{
[Extension()]
public static string ToXmlText(XmlSchema schema)
{
...
}
}

和这些类:

public class XmlFactory<T>
{
...

public XmlFactory(IEnumerable<T> objects)
{
this.Objects = objects;
}

public XmlDocument CreateXml()
{
// serializes objects to XML
}
}

public class XmlSchemaFactory<T> : IXmlSchemaFactory<T>
{
public XmlSchema CreateXmlSchema()
{
// Uses reflection to build schema from type
}
}

最佳答案

在我看来,您正在发现根据 API 所针对的对象模型定义 Fluent API 的局限性。作为Jeremy Miller points out, it's often better to let the Fluent API build a Semantic Model然后可用于构建所需的对象图。

这是我分享的经验,我发现它有助于弥合 Fluent API 和 DI 之间的明显差距。


基于呈现的原始 Fluent API,语义模型可能像这样简单:

public class MySemanticModel
{
public DataSet DataSet { get; set; }
public bool IgnoreSchema { get; set; }
// etc...
}

关于.net - 依赖注入(inject)和 Fluent APIs——遇到了一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6171779/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com