具有可互换数据访问的存储库模式

时间:2013-02-14 11:51:50

标签: c# .net design-patterns repository

我刚刚读到了c#中的存储库模式。它将为实际数据的访问方式提供可互换的层。那很棒。但是,请考虑以下事项:

我有一个XmlPersonRepository,它将从文件中获取XML数据并将其作为c#对象返回(Person.cs POCO)。现在我希望XML数据的物理源也可以互换。最初,它来自一个文件,但它也可以来自Web服务器或资源字符串。我将如何以最可重用的方式实现此功能?我不想写像XmlPersonFromFileRepository和XmlPersonFromWebRepository这样的东西,因为它意味着代码重复。它会复制用于将原始XML数据转换为c#对象的代码,但无论是从文件还是从Web服务获取XML,此代码都保持不变。因此,在两个类中都有转换代码是多余的。

简而言之,我希望有两个抽象层:一个层从任何源获取psysical XML数据,另一个层将此数据转换为c#对象。两者都应该是可以互换的。

我该如何实现?请告诉我这是不是一个好主意,我是否走在正确的轨道上?

2 个答案:

答案 0 :(得分:1)

简单。你只是在你的问题中措辞。

您有两个问题需要解决:

  • 从源获取XML数据
  • 将XML数据转换为C#Object

实施第一个问题:   - IXmlDataGetter,一个从源获取单个XML数据的接口。



    public interface IXmlDataGetter {
      XmlData GetData(XmlDataName name);
    }

" XMLDATA"应该是byte []或Stream(因为XML包含关于数据编码的元数据,我认为它应该保持在字节级别)或者是DOM树(如XmlNode)。您选择最适合您的解决方案。

" XmlDataName"是您识别存储数据的方式。数据有一个名称,但可能很复杂。它可能只是字符串" PERSON"和整数25,是id。 ID为25的人的数据名称可以是一对(" PERSON",25)。

此接口可以为DB实现:



    public class DBXmlDataGetter : IXmlDataGetter {
      XmlData GetData(XmlDataName name) {
        return ResultOfQuery("SELECT xml_text FROM " + name.first /* PERSON */ + " WHERE ID=" + name.second  /* 25 */); 
      }
    }

此接口也可以为文件实现:



    public class FileXmlDataGetter : IXmlDataGetter {
      XmlData GetData(XmlDataName name) {
        return ContentsOfFile(name.first /* PERSON */ + "_" + name.second /* 25 */ + ".xml"); 
      }
    }

当然" ResultOfQuery"和" ContentsOfFile"只是我留给你解决的事情的名称。对于Web,以相同的方式从XmlDataName构建URL。

现在。第二个问题,将XML转换为C#对象。您可以使用XMLDeserializer,或使用XMLReader解析数据并显式构建对象。您只需创建一个执行te作业的类,并将适当的策略作为构造函数参数:



    public class XmlPersonRepository {
      private readonly IXmlDataGetter _getter;

      public PersonFetcher(IXmlDataGetter getter) {
        _getter = getter;
      }

      Person GetFromId(int id) {
        var xmlData = _getter.GetData(new XmlDataName("PERSON", id));
        return ConvertToPerson(xmlData); 
      }
    }

我不会在这里讨论IoC /依赖注入的哲学问题,但这是基本模式。执行转换的类只进行转换。所有它需要从头到尾执行用例得到"注入"来自"以上"。

您已将责任分开,现在您可以根据需要自由地从用户复制/粘贴文本框中获取XML数据。

答案 1 :(得分:0)

如上所述,检查依赖注入/ Ioc是什么,并查看一些框架(如Ninject,Autofac等)。 简而言之,您应该创建一个接口IXmlPersonRepository来定义您的方法,然后在所有不同的类上实现它,它将为您提供像

这样的xml
  • XmlFilePersonRepository:IXmlPersonRepository
  • XmlDBPersonRepository:IXmlPersonRepository

等等。

然后,您将使用接口IXmlPersonRepository来进行调用。 DI位将负责接口的具体实现,并且可以很容易地在db,file等之间进行交换。

相关问题