Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 寻找用于管理需要更新多个数据源中数据的操作的设计模式_C#_Design Patterns_Domain Driven Design_Repository Pattern_Solid Principles - Fatal编程技术网

C# 寻找用于管理需要更新多个数据源中数据的操作的设计模式

C# 寻找用于管理需要更新多个数据源中数据的操作的设计模式,c#,design-patterns,domain-driven-design,repository-pattern,solid-principles,C#,Design Patterns,Domain Driven Design,Repository Pattern,Solid Principles,我有一个带有post操作的api。我们使用C#,每个层都有单独的程序集(Api、业务逻辑、数据访问) 此操作必须与多个数据源交互 检查数据源1中是否已存在该数据 如果数据源1中不存在该数据,请检查数据源2中是否已存在该数据 如果它在数据源2中不存在,请将其插入到数据源1中,然后再插入到数据源2中 我们经常使用服务(用于逻辑)和存储库进行数据访问 选项1 为每个数据源创建一个存储库,每个存储库都有一个get操作和一个insert操作 创建一个使用两个存储库并遵循上述逻辑的服务 优点是,所有的逻

我有一个带有post操作的api。我们使用C#,每个层都有单独的程序集(Api、业务逻辑、数据访问)

此操作必须与多个数据源交互

  • 检查数据源1中是否已存在该数据
  • 如果数据源1中不存在该数据,请检查数据源2中是否已存在该数据
  • 如果它在数据源2中不存在,请将其插入到数据源1中,然后再插入到数据源2中
  • 我们经常使用服务(用于逻辑)和存储库进行数据访问

    选项1

    • 为每个数据源创建一个存储库,每个存储库都有一个get操作和一个insert操作
    • 创建一个使用两个存储库并遵循上述逻辑的服务
    优点是,所有的逻辑都在服务中,感觉更像是“单一责任”。这样做的缺点是,以后有人可以直接使用“datasource 1存储库”并插入一条记录,而不知道该记录也应该插入datasource 2中

    选项2 使用与两个数据源交互的单个get和insert操作创建一个存储库。这将确保你不能与一个没有另一个的人互动,但感觉不到“单一责任”

    选项3 有3个存储库

    • 数据源1的1存储库(但只有内部接口,因此无法被其他程序集使用)
    • 数据源2的1存储库(但只有内部接口,因此无法被其他程序集使用)
    • 1个具有公共接口且可由服务使用的存储库(在不同程序集中)
    公共存储库可以使用2个“特定于数据源”的存储库,并遵循上述逻辑。这将逻辑从服务转移到存储库,但其优点是实现对数据层之外的任何人都是隐藏的


    人们的想法是什么?有这样的设计模式吗?

    需求感觉很像,不幸的是,这对减少数据访问代码的数量没有多大作用。我希望在检查中每个“级别”都有一个读卡器,让它们都实现一些公共接口,并使用责任链(即,如果不要求链中的下一个对象,我可以处理这个问题)来执行操作。您可以将链中的每个项目都设置为迷你存储库,或者根据需要使用另一个存储库


    如果您在结构中已经有了特定的存储库,或者其他地方需要类似的阅读器,那么可能只需要担心它们。

    我为这些愚蠢的绘图道歉,但我试图将您的工作流表示为有限自动机

    所以,我想我们可以这样减少它

    并且只有一个有效的数据源

    此外,如果需要,考虑同步机制,这会导致开销。

    一方面,我可以为每个数据源创建一个存储库,每个存储库都有一个get操作和一个insert操作。然后我可以创建一个遵循上述逻辑的服务

    优点是,所有的逻辑都在服务中,感觉更像是“单一责任”

    我也喜欢这个选项,所以如果我是你,我会选择这个选项

    另一种选择是创建一个存储库,使用一个与两个数据源交互的插入操作。这将确保你不能与一个没有另一个的人互动,但感觉不到“单一责任”

    我不喜欢在一个repo中检查数据源,因为这听起来像是服务层的责任

    另一个选择是拥有3个存储库。1是公共的,由服务(DDD)使用,此存储库只与内部的特定于数据源的存储库对话

    我不知道你所说的“内部”是什么意思。如果“内部”是指部件中的
    internal
    ,则它仍具有与上一选项相同的缺点

    关于我和你都喜欢的第一种选择,你说:

    这样做的缺点是,有人很容易在以后出现,直接使用“datasource 1存储库”插入记录,而不知道也应该将记录插入datasource 2

    我们可以采取一些措施来避免这种情况。创建这样一个类,想象我们正在保存
    Customer

    public class Customer { }
    
    public class CustomerData
    {
        public string MyProperty { get; private set; }
    
        private CustomerData()
        {
        }
    
        public Customer Customer { get; private set; }
    
        // or not void
        public static void Save(Customer customer)
        {
            // Check all datasources and save wherever you need to 
            // obviously through injection or whatever. I will just
            // new-it up here
            var cd = new CustomerData { Customer = customer };
            var repo1 = new CustomerRepository();
            repo1.Save(cd);
    
            bool someCondition = true;
            if (someCondition)
            {
                var repo2 = new CustomerRepository();
                repo2.Save(cd);
            }
        }
    }
    
    请注意,构造函数是私有的,因此开发人员无法创建它。现在按如下方式创建您的存储库:

    public class CustomerRepository
    {
        public void Save(CustomerData cd) { // Save cd.Customer to datasource }
    }
    
    interface Repository {
        void persistSomething(something);
    }
    
    class Source1 implements Repository {
        void persistSomething(something) {
            // insert into database
       }
    }
    
    class Source2AndSource1 implements Repository {
        // inject the right database connection and a Source1 instance
        void persistSomething(something) {
            // Check if the data already exists in datasource 1
            // If it doesn't exist in datasource 1, check if the data already exists in datasource  2
           //If it doesn't exist in datasource 2, insert it in to datasource 1 and then insert it in to datasource 2
       }
    }
    
    请注意,它以
    CustomerData
    作为参数

    好的!因此,让我们使用回购协议:

    var repo = new CustomerRepository();
    // Oops cannot create CustomerData. 
    // repo has no other method except for CustomerData.
    repo.Save(new CustomerData()); 
    
    // There is no other way except for this or the developer has to add 
    // a method to the repo-but what can we do about that, not much!
    CustomerData.Save(new Customer());
    

    从我看到的界面类似于
    persistSomethingToRepository
    。这个接口是客户端代码所关心的全部内容。它不关心您使用辅助遗留系统这一事实(也不应该)。这一观察结果大大简化了实现,因为您可以使用来修饰DataSource1,同时还可以持久化到DataSource2

    我还没有足够的C语言经验,但伪OOP代码是这样的:

    public class CustomerRepository
    {
        public void Save(CustomerData cd) { // Save cd.Customer to datasource }
    }
    
    interface Repository {
        void persistSomething(something);
    }
    
    class Source1 implements Repository {
        void persistSomething(something) {
            // insert into database
       }
    }
    
    class Source2AndSource1 implements Repository {
        // inject the right database connection and a Source1 instance
        void persistSomething(something) {
            // Check if the data already exists in datasource 1
            // If it doesn't exist in datasource 1, check if the data already exists in datasource  2
           //If it doesn't exist in datasource 2, insert it in to datasource 1 and then insert it in to datasource 2
       }
    }
    
    然后,您只需将依赖项注入容器(DIC)配置为在需要
    存储库时使用
    Source2AndSource1
    的实例


    当您的旧系统(源2)不再使用时,您只需将DIC配置为使用
    Source1
    的实例,而不是
    source2和Source1
    ,而无需对客户端代码进行任何修改。这将为您提供一个代码,更准确地说是和。

    数据源是否具有相同的结构和模式?
    我们定期确保服务和存储库
    -我不明白这意味着什么,您能澄清一下吗?Hi@CodingYoshi-数据源不相同。数据源