如何使用依赖注入完成可变对象重构?

时间:2015-12-21 12:25:30

标签: c# dependency-injection dependencies refactoring

在整个代码库中都存在一个“Audit”对象,我正在尝试重构以允许依赖注入,最终更好的单元测试。到目前为止,我已经没有问题为我的类创建接口,并通过构造函数注入它们。然而,这个班级是不同的。我知道为什么/如何不同,但我不确定如何将其修复为“正常”工作。

以下是一个示例(dumbed down版本,但问题在示例中仍然存在):

namespace ConsoleApplication1.test.DI.Original
{
    public class MultiUseDependencies
    {
        public MultiUseDependencies()
        {

        }

        public void Update()
        {
            Audit a = new Audit();
            a.preAuditValues = "Update";

            // if data already exists, delete it
            this.Delete();

            // Update values, implementation not important

            // Audit changes to the data
            a.AuditInformation();
        }

        public void Delete()
        {
            Audit a = new Audit();
            a.preAuditValues = "Delete";

            // Delete data, implementation omitted.

            a.AuditInformation();
        }
    }

    public class Audit
    {
        public string preAuditValues { get; set; }

        public void AuditInformation()
        {
            Console.WriteLine("Audited {0}", preAuditValues);
        }
    }
}

在上面,Update函数(实现未显示)获取数据的“预更改”版本,删除数据(并审核它),插入/更新数据更改,然后审核插入/更新。

如果我要从控制台应用程序运行:

Console.WriteLine("\n");
test.DI.Original.MultiUseDependencies mud = new test.DI.Original.MultiUseDependencies();
mud.Update();

我会得到:

  

审核删除

     

审核更新

这是预期的行为。现在在实现类的方式中,我已经看到会出现问题,但我不确定如何纠正它。用DI来看(初始)重构:

namespace ConsoleApplication1.test.DI.Refactored
{
    public class MultiUseDependencies
    {

        private readonly IAudit _audit;

        public MultiUseDependencies(IAudit audit)
        {
            _audit = audit;
        }

        public void Update()
        {
            _audit.preAuditValues = "Update";

            // if data already exists, delete it
            this.Delete();

            // Update values, implementation not important

            // Audit changes to the data
            _audit.AuditInformation();
        }

        public void Delete()
        {
            _audit.preAuditValues = "Delete";

            // Delete data, implementation omitted.

            _audit.AuditInformation();
        }
    }

    public interface IAudit
    {
        string preAuditValues { get; set; }
        void AuditInformation();
    }

    public class Audit : IAudit
    {
        public string preAuditValues { get; set; }

        public void AuditInformation()
        {
            Console.WriteLine("Audited {0}", preAuditValues);
        }
    }
}

运行:

Console.WriteLine("\n");
test.DI.Refactored.MultiUseDependencies mudRefactored = new test.DI.Refactored.MultiUseDependencies(new test.DI.Refactored.Audit());
mudRefactored.Update();

我得到(正如所料,但不正确):

  

审核删除

     

审核删除

以上是基于实现的预期,但根据原始行为不正确。我不确定如何继续进行。原始实现依赖于不同的Audit来正确跟踪正在发生的变化。当我在重构中传递IAudit的实现时,我只得到Audit的单个实例,其中两个是相互对接的。

基本上在重构之前,Audit的范围是功能级别。在重构之后,Audit作用于该类。

有没有一种简单的方法可以解决这个问题?

这里有一个小提琴: https://dotnetfiddle.net/YbpTm4

1 个答案:

答案 0 :(得分:0)

试试这个:

public void Update()
{
    // if data already exists, delete it
    this.Delete();

    //preAuditValues should be changed after the delete or it will keep 
    //the old value

    _audit.preAuditValues = "Update";

    // Update values, implementation not important

    // Audit changes to the data
    _audit.AuditInformation();
}

或者这也应该有效:

public void Delete()
{
    string oldValue = _audit.preAuditValues;
    _audit.preAuditValues = "Delete";

    // Delete data, implementation omitted.

    _audit.AuditInformation();
    //Restoring oldValue after finished with Delete
    _audit.preAuditValues = oldValue ;
}