【问题标题】:What's the correct way to instantiate an IRepository class from the Controller?从控制器实例化 IRepository 类的正确方法是什么?
【发布时间】:2010-05-08 20:32:45
【问题描述】:

我有以下项目布局:

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)

当控制器对 DAL 项目没有可见性时,ICustomerRepository repository = new CustomerRepository(); 的正确说法是什么?还是我这样做完全错了?

【问题讨论】:

    标签: c# model-view-controller dependency-injection irepository


    【解决方案1】:

    您可以使用 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 容器。我从来没有接触过依赖注入。你能给我解释一下它是如何使用的吗?
    • 使用控制反转 (IoC) 通过管理类型之间的依赖关系来帮助构建松散耦合的系统 - 很多时候一个对象可能依赖于其他对象,例如,您的控制器依赖于您的存储库以填充模型。这些依赖关系可以使用 IoC 容器进行管理,这样当一个类型需要另一个类型的实例时,它会向容器请求它,并且容器会返回它配置为返回的类型的实例......
    • 例如,您的控制器想要ICustomerRepository 的具体实例,因此它向容器请求它。不过,我们可以更进一步,我们也可以让容器管理控制器的实例化。我们在这里拥有的优势以及使用 IoC 容器的众多原因之一是,在实例化控制器时,容器将意识到它依赖于 ICustomerRepository 并实例化它的实例(称为依赖注入) .
    • 查看 Martin Fowler 关于 IoC 和依赖注入的文章 - martinfowler.com/articles/injection.html。您可能还对查看 Microsoft Unity 感兴趣。这里有一些介绍文章 - msdn.microsoft.com/en-us/library/ff650320.aspx 和这里 msdn.microsoft.com/en-us/library/ff650806.aspx
    • 干杯拉斯。我现在就去。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    相关资源
    最近更新 更多