使用多个数据源为单个对象构建应用程序

时间:2022-04-14 09:44:11

I'm struggling finding a right solution for my application architecture. For my application I have a single class for customers. The data for filling my customer objects are spread over multiple different types of datasources. The main part is exposed in a readonly Oracle database, other parts are exposed using a webservices and I need te save some extra data to another datasource (for instance a MS SQL database using entityframework) since I only have readonly rights for most datasouces (they are managed somewhere else).

我正在努力为我的应用程序架构找到合适的解决方案。对于我的应用程序,我为客户提供单一课程。用于填充客户对象的数据分布在多种不同类型的数据源上。主要部分暴露在只读Oracle数据库中,其他部分使用Web服务公开,我需要将一些额外数据保存到另一个数据源(例如使用entityframework的MS SQL数据库),因为我只拥有大多数数据的只读权限(它们)在其他地方管理)。

For this reason I wanna build some kind of central library with connectors to all of my datasources for creating a centralized Customer Object to work with. So far so good for this idea (I think) but I can't find any documentation or example with best practices how to achieve such a solution.

出于这个原因,我想构建某种*库,其中包含所有数据源的连接器,用于创建集中的客户对象。到目前为止,这个想法非常好(我认为),但我找不到任何文档或最佳实践示例如何实现这样的解决方案。

EXAMPLE:
  * Main Application (multiple applications)
     - Central Business Logic Layer (Business-API)
         * Webservice Connector
         * Oracle Connector
         * EntityFramework Connector

Does anyone know if there is some good reading material on this specific subject?

有谁知道这个特定主题是否有一些好的阅读材料?

Kind regards

3 个解决方案

#1


The specific problem you describe with customer objects sounds a lot like the one solved by the Data Mapper pattern, which is technically a kind of Mediator. Quoting from the Wikipedia page for Data Mapper:

您使用客户对象描述的具体问题听起来很像Data Mapper模式解决的问题,这在技术上是一种Mediator。从Datapedia的Wikipedia页面引用:

A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself. The layer is composed of one or more mappers (or Data Access Objects), performing the data transfer. Mapper implementations vary in scope. Generic mappers will handle many different domain entity types, dedicated mappers will handle one or a few.

数据映射器是一种数据访问层,它在持久数据存储(通常是关系数据库)和内存数据表示(域层)之间执行数据的双向传输。模式的目标是保持内存表示和持久数据存储彼此独立以及数据映射器本身。该层由一个或多个映射器(或数据访问对象)组成,执行数据传输。映射器实现的范围不同。通用映射器将处理许多不同的域实体类型,专用映射器将处理一个或几个。

Although the language of the problem above speaks of a persistent data store that's singular, there's no reason why it couldn't be several data locations (Mediator pattern hides the details from the collaborators).

虽然上面问题的语言提到了一个单数的持久性数据存储,但没有理由说它不能是多个数据位置(Mediator模式隐藏了协作者的详细信息)。

There is an extension of this pattern, known as the Repository pattern:

这种模式有一个扩展,称为Repository模式:

#2


I suggest the DAO-Pattern to abstract from any data access. The business logic should not be aware of any datasources. This is the most important aim. Anything else has to be subordinated.

我建议DAO-Pattern从任何数据访问中抽象出来。业务逻辑不应该知道任何数据源。这是最重要的目标。其他任何东西都必须是从属的。

#3


You can create a constructor that accepts datasources like:

您可以创建一个接受数据源的构造函数,如:

public class Customer
{
    public Customer(OracleConnector oracle, WebSerivceConnector webservice, EntityConnector entity)
    {
        this.oracle = oracle;
        this.webservice = webservice;
        this.entity = entity;
    }

    public void Fetch()
    {
        // fetch data from oracle, webservice, and entity.
        this.Name = oracle.GetCustomerName();
    }
}

This way only Customer knows how to get the data, all the logic is in one place. You can even make it more testable and less coupling by creating interfaces for connectors.

这种方式只有客户知道如何获取数据,所有逻辑都在一个地方。您甚至可以通过为连接器创建接口来使其更易于测试并减少耦合。

public interface IOracleConnector
{
    // add something here
    string GetCustomerName();
}

public class OracleConnector
    : IOracleConnector
{
    // add the implementation here.
}

Then change Customer constructor to accepts IOracleConnector like:

然后更改Customer构造函数以接受IOracleConnector,如:

public Customer(IOracleConnector oracle, WebSerivceConnector webservice, EntityConnector entity)
{
    // your code here.
} 

Now, you can create a mock to test Customer without actually connecting to the database.

现在,您可以创建一个模拟来测试Customer,而无需实际连接到数据库。

#1


The specific problem you describe with customer objects sounds a lot like the one solved by the Data Mapper pattern, which is technically a kind of Mediator. Quoting from the Wikipedia page for Data Mapper:

您使用客户对象描述的具体问题听起来很像Data Mapper模式解决的问题,这在技术上是一种Mediator。从Datapedia的Wikipedia页面引用:

A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself. The layer is composed of one or more mappers (or Data Access Objects), performing the data transfer. Mapper implementations vary in scope. Generic mappers will handle many different domain entity types, dedicated mappers will handle one or a few.

数据映射器是一种数据访问层,它在持久数据存储(通常是关系数据库)和内存数据表示(域层)之间执行数据的双向传输。模式的目标是保持内存表示和持久数据存储彼此独立以及数据映射器本身。该层由一个或多个映射器(或数据访问对象)组成,执行数据传输。映射器实现的范围不同。通用映射器将处理许多不同的域实体类型,专用映射器将处理一个或几个。

Although the language of the problem above speaks of a persistent data store that's singular, there's no reason why it couldn't be several data locations (Mediator pattern hides the details from the collaborators).

虽然上面问题的语言提到了一个单数的持久性数据存储,但没有理由说它不能是多个数据位置(Mediator模式隐藏了协作者的详细信息)。

There is an extension of this pattern, known as the Repository pattern:

这种模式有一个扩展,称为Repository模式:

#2


I suggest the DAO-Pattern to abstract from any data access. The business logic should not be aware of any datasources. This is the most important aim. Anything else has to be subordinated.

我建议DAO-Pattern从任何数据访问中抽象出来。业务逻辑不应该知道任何数据源。这是最重要的目标。其他任何东西都必须是从属的。

#3


You can create a constructor that accepts datasources like:

您可以创建一个接受数据源的构造函数,如:

public class Customer
{
    public Customer(OracleConnector oracle, WebSerivceConnector webservice, EntityConnector entity)
    {
        this.oracle = oracle;
        this.webservice = webservice;
        this.entity = entity;
    }

    public void Fetch()
    {
        // fetch data from oracle, webservice, and entity.
        this.Name = oracle.GetCustomerName();
    }
}

This way only Customer knows how to get the data, all the logic is in one place. You can even make it more testable and less coupling by creating interfaces for connectors.

这种方式只有客户知道如何获取数据,所有逻辑都在一个地方。您甚至可以通过为连接器创建接口来使其更易于测试并减少耦合。

public interface IOracleConnector
{
    // add something here
    string GetCustomerName();
}

public class OracleConnector
    : IOracleConnector
{
    // add the implementation here.
}

Then change Customer constructor to accepts IOracleConnector like:

然后更改Customer构造函数以接受IOracleConnector,如:

public Customer(IOracleConnector oracle, WebSerivceConnector webservice, EntityConnector entity)
{
    // your code here.
} 

Now, you can create a mock to test Customer without actually connecting to the database.

现在,您可以创建一个模拟来测试Customer,而无需实际连接到数据库。