我是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 constructor
是parameterize
所以当用户请求像Users\index\10
这样的页面时,将调用控制器构造函数但是如何在那里传递参数....... .....我不清楚这一点。
答案 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());