C# 未调用ASP MVC控制器

C# 未调用ASP MVC控制器,c#,asp.net-mvc,C#,Asp.net Mvc,为了让我自己更容易对我的应用程序进行单元测试,我尝试通过将数据访问功能移动到一个单独的存储库类中来实现存储库模式 我的存储库中的我的数据访问类: public class ErrorRepository : IErrorRepository { public ErrorModel Errors { get; set; } public List<ErrorModel> ErrorList { get; set; } public List<ErrorM

为了让我自己更容易对我的应用程序进行单元测试,我尝试通过将数据访问功能移动到一个单独的存储库类中来实现存储库模式

我的存储库中的我的数据访问类:

public class ErrorRepository : IErrorRepository
{
    public ErrorModel Errors { get; set; }
    public List<ErrorModel> ErrorList { get; set; }

    public List<ErrorModel> GetErrors()
    {
        string cs = "some path";

        using (SQLiteConnection con = new SQLiteConnection(cs))
        {
            var listOfErrors = new List<ErrorModel>();
            string stm = "SELECT * FROM Error WHERE Checked == 'False'";
            con.Open();

            using (SQLiteCommand cmd = new SQLiteCommand(stm, con))
            {
                using (SQLiteDataReader rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        listOfErrors.Add(new ErrorModel
                        {
                            Id = rdr["ID"].ToString()
                        });
                    }

                    rdr.Close();
                    ErrorList = listOfErrors;
                }
            }

            con.Close();
        }

        return ErrorList;
    }
}

public interface IErrorRepository
{
    List<ErrorModel> GetErrors();
}
    public ErrorController(IErrorRepository errorRepository)
    {
        this.errorRepository = errorRepository;
    }
但问题是,控制器永远不会被调用

我改变了以前的版本,控制器负责一切。所以我所做的就是把访问的数据转移到一个单独的类中。错误视图与以前相同。我的实现中是否遗漏了一些细节

更新:

我对构造函数做了一些修改,我有几个问题。为什么我在构造函数中注入的以下代码不起作用:

    public ErrorController(IErrorRepository _errorRepository)
    {
        this._errorRepository = _errorRepository;
    }
但如果我将其更改为此,控制器将被调用,并且一切似乎都正常工作:

    public ErrorController()
    {
        _errorRepository = new ErrorRepository();
    }
但最后一个例子不是一种很糟糕的方法吗,因为ErrorController仍然与ErrorRepository紧密耦合

更新2:

我在工厂制作了这个定制控制器:

public class ControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        try
        {
            if (controllerType == null)
            {
                throw new ArgumentNullException("controllerType");
            }
            if (!typeof (IController).IsAssignableFrom(controllerType))
            {
                throw new ArgumentException(string.Format("Type requested is not a controller: {0}", controllerType.Name), "controllerType");
            }
            return MvcUnityContainer.Container.Resolve(controllerType) as IController;
        }
        catch (Exception)
        {
            return null;
        }
    }
}

public static class MvcUnityContainer
{
    public static UnityContainer Container { get; set; }
}
此引导程序类用于设置所有依赖项:

public class Bootstrapper
{
    public static IUnityContainer Initialise()
    {
        var container = BuildUnityContainer();
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

        return container;
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
        container.RegisterType<IErrorRepository, ErrorRepository>();
        MvcUnityContainer.Container = container;

        return container;
    }
}
现在我可以使用构造函数注入,从而将ErrorController与ErrorRepository解耦:

public class ErrorRepository : IErrorRepository
{
    public ErrorModel Errors { get; set; }
    public List<ErrorModel> ErrorList { get; set; }

    public List<ErrorModel> GetErrors()
    {
        string cs = "some path";

        using (SQLiteConnection con = new SQLiteConnection(cs))
        {
            var listOfErrors = new List<ErrorModel>();
            string stm = "SELECT * FROM Error WHERE Checked == 'False'";
            con.Open();

            using (SQLiteCommand cmd = new SQLiteCommand(stm, con))
            {
                using (SQLiteDataReader rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        listOfErrors.Add(new ErrorModel
                        {
                            Id = rdr["ID"].ToString()
                        });
                    }

                    rdr.Close();
                    ErrorList = listOfErrors;
                }
            }

            con.Close();
        }

        return ErrorList;
    }
}

public interface IErrorRepository
{
    List<ErrorModel> GetErrors();
}
    public ErrorController(IErrorRepository errorRepository)
    {
        this.errorRepository = errorRepository;
    }

好的,我通过阅读关于如何团结国际奥委会的优秀文章,解决了这个问题。我已经用我的最终代码更新了OP。

根据我的经验,Ninject是一个很好的IoC容器。您可以从下载并运行我的ASP.NET MVC项目。我使用了从低级到高级的依赖注入。希望这能让您了解Ninject框架以及为什么我们要维护依赖倒置原则

您是否有某种IoC注入
IErrorController
?它很可能无法命中控制器,因为您没有空构造函数,也可能没有DI设置。您所说的“控制器从未被调用”是什么意思?您提出了什么请求,得到了什么响应?作为对您的更新的响应,第一个不起作用,因为您没有设置DI容器(Autofac、Unity等)将
ErrorRepository
的实例实际注入到
ErrorController
中,以满足对
ierErrorRepository
的依赖性。使用DI容器,您可以注册应该使用哪些类型来满足依赖关系,然后容器可以处理创建该类型的实例并将其提供给控制器。正确的是,第二种方法与
ErrorRepository
紧密耦合,应该避免使用,因为不可能隔离@Khaine775,这取决于您选择的DI容器。我使用了Ninject,它有一个特殊的属性,可以注册它在启动时运行。与其他人一起,您可以向global.asax添加一些内容。只需选择一个著名的DI容器,并检查他们的文档,了解如何注册它和设置依赖项。既然您已经掌握了存储库模式,为什么不继续下一步,实现服务模式,在该模式中,所有逻辑都从控制器中取出并在服务中执行。此服务将业务逻辑与UI逻辑分离,并以与注入存储库相同的方式注入。这个线程中公认的答案就是一个例子:你是指依赖注入原理还是控制反转原理?lolIt的依赖倒置原理。这是通过控制反转来实现的。依赖项注入是反转控件的一种方法,因此我们保持依赖项反转原则。:)