从第三方数据源导入数据(开放架构设计)
当我们有固定的数据库设计并且需要支持从第三方数据源(很可能是 XML 格式)导入数据时,您将如何在 .NET 中设计应用程序(类、类库中的接口)?
例如,假设我们的数据库中有一个产品表,其中包含列 ID 标题 描述 税级 价格
,另一方面我们有例如产品: 产品编号 产品标题 文本 基本价格 数量。
目前我这样做: 将第三方 XML 转换为类和 XSD,然后将其内容反序列化为强类型对象(此过程的结果是 ThirdPartyProduct、ThirdPartyClassification 等类)。
然后我有这样的方法:
InsertProduct(ThirdPartyProduct newproduct)
我目前不使用接口,但我想使用。我想要的是实现类似
public class Contoso_ProductSynchronization : ProductSynchronization
{
public void InsertProduct(ContosoProduct p)
{
Product product = new Product(); // this is our Entity class
// do the assignments from p to product here
using(SyncEntities db = new SyncEntities())
{
// ....
db.AddToProducts(product);
}
}
// the problem is Product and ContosoProduct have no arhitectural connection right now
// so I cannot do this
public void InsertProduct(ContosoProduct p)
{
Product product = (Product)p;
using(SyncEntities db = new SyncEntities())
{
// ....
db.AddToProducts(product);
}
}
}
ProductSynchronization 是接口或抽象类的东西。 ProductSynchronization 很可能有多种实现。我无法对类型进行硬编码 - 像 ContosoProduct、NorthwindProduct 这样的类可能是从第三方 XML 创建的(因此我最好继续使用反序列化)。
希望有人能理解我在这里试图解释的内容。试想一下,您是卖家,并且您有许多提供商,并且每个提供商都使用自己专有的 XML 格式。我不介意开发,当然每次新格式出现时都需要开发,因为它只需要实现10-20个方法,我只是希望架构是开放的并支持它。
在您的回复中,请重点关注设计,而不是过多关注数据访问技术,因为大多数技术都非常易于使用(如果您需要知道,EF 将用于与我们的数据库交互)。
How would you design an application (classes, interfaces in class library) in .NET when we have a fixed database design on our side and we need to support imports of data from third party data sources, which will most likely be in XML?
For instance, let us say we have a Products table in our DB which has columns
Id
Title
Description
TaxLevel
Price
and on the other side we have for instance Products:
ProductId
ProdTitle
Text
BasicPrice
Quantity.
Currently I do it like this:
Have the third party XML convert to classes and XSD's and then deserialize its contents into strong typed objects (what we get as a result of this process is classes like ThirdPartyProduct, ThirdPartyClassification, etc.).
Then I have methods like this:
InsertProduct(ThirdPartyProduct newproduct)
I do not use interfaces at the moment but I would like to. What I would like is implement something like
public class Contoso_ProductSynchronization : ProductSynchronization
{
public void InsertProduct(ContosoProduct p)
{
Product product = new Product(); // this is our Entity class
// do the assignments from p to product here
using(SyncEntities db = new SyncEntities())
{
// ....
db.AddToProducts(product);
}
}
// the problem is Product and ContosoProduct have no arhitectural connection right now
// so I cannot do this
public void InsertProduct(ContosoProduct p)
{
Product product = (Product)p;
using(SyncEntities db = new SyncEntities())
{
// ....
db.AddToProducts(product);
}
}
}
where ProductSynchronization will be an interface or abstract class. There will most likely be many implementations of ProductSynchronization. I cannot hardcode the types - classes like ContosoProduct, NorthwindProduct might be created from the third party XML's (so preferably I would continue to use deserialization).
Hopefully someone will understand what I'm trying to explain here. Just imagine you are the seller and you have numerous providers and each one uses their own proprietary XML format. I don't mind the development, which will of course be needed everytime new format appears, because it will only require 10-20 methods to be implemented, I just want the architecture to be open and support that.
In your replies, please focus on design and not so much on data access technologies because most are pretty straightforward to use (if you need to know, EF will be used for interacting with our database).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
[编辑:设计说明]
好吧,从设计的角度来看,我会对传入的 xml 进行 xslt 以将其转换为统一格式。也很容易根据模式验证结果 xml。
使用 xslt,我将远离任何接口或抽象类,而在我的代码中只有一个类实现,即内部类。它将使代码库保持干净,并且如果数据像您所说的那样简单,那么 xslt 本身应该非常短。
只要有项目文档,就可以轻松地记录转换。
如果您决定绝对希望每个 xml 有一个类(或者如果您可能从某个客户那里获得了 .net dll 而不是 xml),那么我会让代理类继承一个接口或抽象类(基于您的内部类,并根据需要在代理类中实现每个属性的映射,这样您就可以将任何类转换为您的基/内部类,
我看来,在代码中进行转换/映射会使代码设计变得更加混乱。
但在 >[原始答案]
如果我理解正确,您想将 ThirdPartyProduct 类映射到您自己的内部类,
最初我正在考虑使用类似 Automapper 并在创建 xml 反序列化代理时配置映射。如果您使反序列化最终使用与内部类相同的属性名称,那么配置就会更少为映射器做的事情。
我想听听任何人对这条路线的想法。
另一种方法是在 Converter 类中添加
.ToInternalProduct( ThirdPartyClass )
。当您添加更多外部类时,请不断添加更多。第三种方法适用于 XSLT 人员。如果您喜欢 XSLT,您可以将 xml 转换为可以反序列化到您的内部产品类中的内容。
我选择这三个中的哪一个取决于程序员的技能以及谁将继续添加新的外部类。当新格式出现时,XSLT 方法不需要重新编译或编译代码。这可能是一个优势。
[EDIT: Design note]
Ok, from a design perspective I would do xslt on the incoming xml to transform it to a unified format. Also very easy to verify the result xml towards a schema.
Using xslt I would stay away from any interface or abstract class, and just have one class implementation in my code, the internal class. It would keep the code base clean, and the xslt's themselves should be pretty short if the data is as simple as you state.
Documenting the transformations can easily be done wherever you have your project documentation.
If you decide you absolutely want to have one class per xml (or if you perhaps got a .net dll instead of xml from one customer), then I would make the proxy class inherit an interface or abstract class (based off your internal class, and implement the mappings per property as needed in the proxy classes. This way you can cast any class to your base/internal class.
But seems to me doing the conversion/mapping in code will make the code design a bit more messy.
[Original Answer]
If I understand you correctly you want to map a ThirdPartyProduct class over to your own internal class.
Initially I am thinking class mapping. Use something like Automapper and configure up the mappings as you create your xml deserializing proxy's. If you make your deserialization end up with the same property names as your internal class, then there's less config to do for the mapper. Convention over Configuration.
I'd like to hear anyones thoughts on going this route.
Another approach would be to add a
.ToInternalProduct( ThirdPartyClass )
in a Converter class. And keep adding more as you add more external classes.The third approach is for XSLT guys. If you love XSLT you could transform the xml into something which can be deserialized into your internal product class.
Which one of these three I'd choose would depend on the skills of the programmer, and who will maintain adding new external classes. The XSLT approach would require no recompiling or compiling of code as new formats arrived. That might be an advantage.