ASP.Net MVC中的参数化控制器Ctor

时间:2015-09-07 09:24:24

标签: asp.net-mvc-4 repository-pattern

我是MVC的新手。所以我正在阅读一篇关于repository design pattern的文章,有一件事出现在我眼前并不清楚。这是代码......首先看代码。

public interface IUsersRepository
{
    public User GetUser(int id);
}

然后实施它:

public class UsersRepository: IUsersRepository
{
    private readonly string _connectionString;
    public UsersRepository(string connectionString)
    {
        _connectionString = connectionString;
    }

    public User GetUser(int id)
    {
        // Here you are free to do whatever data access code you like
        // You can invoke direct SQL queries, stored procedures, whatever 

        using (var conn = new SqlConnection(_connectionString))
        using (var cmd = conn.CreateCommand())
        {
            conn.Open();
            cmd.CommandText = "SELECT id, name FROM users WHERE id = @id";
            cmd.Parameters.AddWithValue("@id", id);
            using (var reader = cmd.ExecuteReader())
            {
                if (!reader.Read())
                {
                    return null;
                }
                return new User
                {
                    Id = reader.GetInt32(reader.GetOrdinal("id")),
                    Name = reader.GetString(reader.GetOrdinal("name")),
                }
            }
        }
    }
}

然后您的控制器可以使用此存储库:

public class UsersController: Controller
{
    private readonly IUsersRepository _repository;
    public UsersController(IUsersRepository repository)
    {
        _repository = repository;
    }

    public ActionResult Index(int id)
    {
        var model = _repository.GetUser(id);
        return View(model);
    }
}

查看控制器代码。当用户请求类似Users\index\10的页面时,此操作将被调用public ActionResult Index(int id){}我的问题是此方法的工作原理_repository.GetUser(id); ?因为何时会调用ctor UsersController()那么存储库实例将如何通过那里?

我的问题是,如果任何类有parameterize构造函数,那么当我们需要创建该类的实例时,我们需要传递参数值。

在这种情况下controller constructorparameterize所以当用户请求像Users\index\10这样的页面时,将调用控制器构造函数但是如何在那里传递参数....... .....我不清楚这一点。

请帮助我理解。感谢

1 个答案:

答案 0 :(得分:1)

这项工作可以使用Dependency Injection(DI) framework完成。

DI - 消除了我们感兴趣的类(消费者类)所依赖的其他对象实例(在UML意义上)的直接创建和生命管理的责任。这些实例传递给我们的使用者类,通常作为构造函数参数或通过属性设置器(依赖对象实例化和传递给使用者类的管理通常由控制反转(IoC)容器执行,但这是另一个主题)

有关详细信息,请阅读文章:ASP.NET MVC 4 Dependency Injection.
另外,我建议您阅读书籍Pro ASP.NET MVC by Adam Freeman,该书描述了与Ninject等DI容器的良好配合。 请参阅What is dependency injection?

我举一个小例子:
我们创建了两个构造函数,第一个没有用于单元测试的参数:

public BaseApiController()
{
   repository = unitOfWork.EFRepository<T>();
}

第二个带依赖注入的构造函数:

public BaseApiController(IRepository<T> repository)
{
  this.repository = repository;
}

然后,对于使用像Ninject这样的DI容器,我们需要创建和配置Controller Factory:

    public class NinjectControlFactory : DefaultControllerFactory
    {
        private IKernel ninjectKernel;
        public NinjectControlFactory()
        {
            //create container
            ninjectKernel = new StandardKernel();
            AddBindings();
        }

        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            return controllerType == null
                ? null
                : (IController)ninjectKernel.Get(controllerType);
        }

        private void AddBindings()
        {
            //congif container
            ninjectKernel.Bind(typeof(IRepository<>)).To(typeof(EFRepository<>));
        }
    }

最后,我们必须在Global.asax文件的Application_Start()中注册容器:

ControllerBuilder.Current.SetControllerFactory(new NinjectControlFactory());