如何正确从控制器实例化一个IRepository类?

3
我有以下的项目布局:
MVC UI
|...CustomerController (ICustomerRepository - how do I instantiate this?)

Data Model
|...ICustomerRepository

DAL (Separate Data access layer, references Data Model to get the IxRepositories)
|...CustomerRepository (inherits ICustomerRepository)

当控制器无法访问数据访问层项目时,如何正确地说出ICustomerRepository repository = new CustomerRepository();?或者我完全错了吗?
1个回答

2
您可以使用一个 IoC 容器来解决映射问题,通过注册您自己的控制器工厂,允许容器解析控制器 - 容器将解析控制器类型并注入接口的具体实例。
例如使用Castle Windsor
在您的 MvcApplication 类的 global.asax 中:
protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory());
}

WindsorControllerFactory类
using System;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using System.Web.Routing;
using Castle.Core.Resource;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;

public class WindsorControllerFactory : DefaultControllerFactory
{
    WindsorContainer container;

    public WindsorControllerFactory()
    {
        container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

        var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                              where typeof(IController).IsAssignableFrom(t)
                              select t;

        foreach (Type t in controllerTypes)
            container.AddComponentWithLifestyle(t.FullName, t, Castle.Core.LifestyleType.Transient);
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        // see http://stackoverflow.com/questions/1357485/asp-net-mvc2-preview-1-are-there-any-breaking-changes/1601706#1601706
        if (controllerType == null) { return null; }

        return (IController)container.Resolve(controllerType);
    }
}

很抱歉我从未听说过IoC容器,也从未接触过依赖注入。你能给我解释一下它是如何使用的,并且举个例子吗? - djdd87
使用控制反转(IoC)有助于构建松散耦合的系统,通过管理类型之间的依赖关系 - 很多时候一个对象可以依赖于其他对象,例如,您的控制器依赖于您的存储库来填充模型。这些依赖关系可以使用IoC容器进行管理,以便当一个类型需要另一个类型的实例时,它会向容器请求,并且容器返回配置为返回该类型实例的类型的实例... - Russ Cam
例如,您的控制器想要一个ICustomerRepository的具体实例,因此它向容器请求。但我们可以更进一步,我们也可以让容器管理控制器的实例化。使用IoC容器的优点之一是,在实例化控制器时,容器将意识到它依赖于ICustomerRepository并实例化该依赖项(称为依赖注入)。 - Russ Cam
谢谢Russ。我现在会尝试一下。 - djdd87
如果您有任何问题,请在StackOverflow上发布问题 :) 您的UI项目将需要引用您的模型项目和DAL项目(如果您不使用IoC,它将需要这样做)。您可以稍后创建您的DAL,并在容器配置中映射存根/虚拟存储库以在解析接口类型时返回。也许将伪造的存储库放在您的模型项目中,使其全部工作,然后再考虑从哪里获取真实数据 :) - Russ Cam
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接