对于我的ASP.NET MVC项目,我曾经非常依赖静态方法进行数据访问,就像这样:

public class MyTable
{

    public static IEnumerable<MyTable> findAll()
    {
        using (var connection = new SqlConnection(Provider.connString))
        {
            //implementation here
        }


        return datas;
    }

    public static MyTable find(guid id)
    {
        using (var connection = new SqlConnection(Provider.connString))
        {
            //implementation here
        }

    }

}

所以我可以在 Controller 中这样称呼他们:

var datas = MyTable.findAll();

我对此很满意,但是我怀疑我在使用它进行数据访问方面做得很好。

现在,我正试图将依赖项注入(inject)仅出于某种学习目的而应用到我的数据访问类中,如下所示:

public class MyTable
{

    public IDatabaseEngine _engine = null;

    public MyTable()
    {
    }

    public MyTable(IDatabaseEngine engine)
    {
        _engine = engine;
    }

    public IEnumerable<MyTable> findAll()
    {
        using (var connection = _engine.getConnection())
        {
            //implementation here
        }
        return datas;
    }

    public MyTable find(guid id)
    {
        using (var connection = _engine.getConnection())
        {
            //implementation here
        }
        return data;
    }
}

事实是,这意味着我必须创建MyTable类的实例才能在 Controller 上调用数据访问方法,如下所示:
var table = new MyTable(new MSSQLEngine(provider.connString));
var datas = table.findAll();

好吧,或者我没有足够的经验来解决这个问题,或者我做错了,我为每次需要的数据访问都对对象进行实例化感到不自在。

我的问题是
  • 我是否执行了依赖注入(inject)错误? (我想是)
  • 创建要调用的数据访问类的对象是一种好习惯吗
    Controller 或其他类中的数据访问方法?
  • 用静态方法代替它是一种好习惯吗? (就像我
    在第一个示例中执行)
  • 如果我的DI实现错误,我该如何正确设置?
  • 最佳答案

    您的问题的答案:

  • 不,请参见下面的详细答案
  • DI的主要优点是依赖于抽象而不是实现。您不需要创建类的实例,DI会为您完成。您只需要将接口(interface)注入(inject)类并在IoC中注册它们。
  • 不,因为您将无法向方法编写单元测试。
  • 参见下文。

  • 为了正确使用DI,首先需要将MyTable类提取到接口(interface)中,然后将该接口(interface)注入(inject)到 Controller 中。
    public interface IMyTable
    {
        IEnumerable<MyTable> findAll();
        // other methods
    }
    
    public class MyTable : IMyTable
    {
        // your implementation
    }
    

    然后,您的 Controller 应如下所示:
    public class YourController : Controller
    {
        private IMyTable myTable;
        public YourController(IMyTable myTable)
        {
            this.myTable = myTable;
        }
    
        public ActionResult YourAction()
        {
            var result = myTable.findAll();
            // ...
        }
    }
    

    我个人将CaSTLe Windsor用作IoC容器,在ASP.NET MVC应用程序中使用CaSTLe Windsor的here is an example

    09-13 03:23