如何对使用Servicestack Funq IOC

时间:2017-01-31 12:27:53

标签: c# unit-testing mocking ormlite-servicestack servicestack-ioc

我是一个我应该扩展的项目的新手,所以我决定使用TDD来快速识别我不完全理解的系统的任何问题。

有一个名为DBService的类,其中包含#34;"所有的数据库访问。例如,有一个名为getAllCustomers的方法,它返回Customers的列表。这看起来像这样(这只是一个更好理解的例子):

public class DBService
{
    public IDbConnectionFactory DBFactory { 
        get { return DI.Container.Resolve<IDbConnectionFactory>(); }
    }

    public List<Customer> GetAllCustomers()
    {
        try
        {
            using (var connection = DBFactory.OpenDbConnection())
            {
                var dbResult = connection.Select<Customer>();
                // code ommitted
            }
        }
        catch (Exception e)
        {
            // code ommitted
        }
    }      
}

另一个问题是,在开始时(在ServiceStack AppHost.Configure中),如果它们不存在,则创建所有表;对于某些表,如果它们存在,则添加一些列等(这可能是稍后添加的更改) )

当我现在例如必须扩展客户并添加另一个字段时,地址我想用TDD风格做,但我不知道如何。

  1. 由于getter是私有的,我无法注入任何DBFactory
  2. Afaik我无法使用:memory:的{​​{1}}连接字符串,因为我使用的是ServiceStack 3.9.74
  3. 那么我的选择是什么?

1 个答案:

答案 0 :(得分:2)

避免使用Service Locator反模式并使用构造函数注入。尽量不要在依赖类中直接使用DI容器。它将您的类紧密地耦合到不属于那里的问题,并且难以单独测试类。

public class DBService {
    private readonly IDbConnectionFactory connectionFactory;

    public DBService(IDbConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }

    public IDbConnectionFactory DBFactory { get { return connectionFactory; } }

    public List<Customer> GetAllCustomers() {
        try {
            using (var connection = DBFactory.OpenDbConnection()) {
                var dbResult = connection.Select<Customer>();
                //... code omitted for brevity
            }
        } catch (Exception e) {
            //... code omitted for brevity
        }
    }
}

Select<T>OpenDbConnection看起来都像扩展方法。我建议检查他们的期望是什么,并嘲笑这些行为。

如果DbService本身被用作其他类的依赖项,则该类也应该被抽象化。

public interface IDbService {
    IDbConnectionFactory DBFactory { get; }
    List<Customer> GetAllCustomers();
}

并实现继承

public class DbService : IDbService { 
    //... code removed for brevity
}

并确保使用IoC容器注册所有内容。