Using StructureMap with the ASP.NET MVC framework

 原文地址:http://www.bengtbe.com/blog/post/2009/02/27/Using-StructureMap-with-the-ASPNET-MVC-framework.aspx


Using StructureMap with the ASP.NET MVC framework


2009-02-27 星期五 作者:bengtbe

在这里我要阐述的是怎么用.net frameword 框架下的StructureMap这个类.  
在学习这个之间你需要对ASP.NET MVC框架,依赖注入和控制反转有基本的了解。
这些技术也不只用于 StructureMap ,如果你喜欢这些,那么你当然也用其它的DI/Ioc  工具了。

我们就用这个UserController 例子还说起,它有一个属性IUserService 来调用控制层的服务,当

然IUserService 本身也会调用 IUserPepository 这个在数据层的方法。这个UserController 用

控制反转来访问IUserService ,这就是说这个UserService 类就是选用控制反转来注入

UserController 实例化IUserService;
public class UserController : Controller
{
    private readonly IUserService m_UserService;
    public UserController(IUserService userService)
    {
        m_UserService = userService;
    }
    public ActionResult Edit(int id)
    {
        return View(m_UserService.GetById(id));
    }
}
这就叫容器注入,如果你就这样写而没有写其它的配置文件那么你将得到如下的错误:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 No parameterless constructor defined for this object.

Description: An unhandled exception occurred during the execution of the current web

request. Please review the stack trace for more information about the error and where

it originated in the code.

Exception Details: System.MissingMethodException: No parameterless constructor defined

for this object.  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
其实默认的,这个ASP.NET MVC framework 是需要一个构造函数的,一种方法是构造形式如下:
public UserController() : this(new UserService(new UserRepository()))
{
}
上面的代码运行时就是调用这个来构造的。你要解决上错的错误可以重写这个构造函数,这种方式

叫Poor Man's Dependency Injection(不明智人选择的次等办法),如果知道DI/Ioc你会另有所选

.
上面的方法还有一个很大的缺点(这个我深有体会^^_^^)就是你把这个接口写死了就是用

UserService 初始化 IUserService ,同理你也许用同样的方法来处理 UserService 中的

UserRepository .这样就把视图层和数据层联系起来了。这时如果UserRepository 再有几个属性

的话,就有看头了,好像那样写代码写丑了一点儿。。。

言归正转我们来用这个StructureMap 的ObjectFactory 来实现相同的效果吧,(初始化

IuserService)代码如下:
public UserController() : this(ObjectFactory.GetInstance<IUserService>())
{
}
很简单的代码!这样这个属性就被初始化了,然而这时每个Controller 都要这样才能达到效果,有

没有更简单的方法呢?让我们来达到尽量简化的目地。
ASP.NET MVC framework 用这个factory 参数来初始化controllers,还提供了一个基类
DefaultControllerFactory 让你更加自由的初始化controller:
public class StructureMapControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(Type controllerType)
    {
        if(controllerType == null) return null;
        try
        {
            return ObjectFactory.GetInstance(controllerType) as Controller;
        }
        catch (StructureMapException)
        {
            System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
            throw;
        }
    }
}
当我们每次调用controller 时就会调用这个方法.上面这段代码就是MstrutureMap的
ObjectFactory 来定制Controller的过程即使你的类中不只一个接口时也没有关系,它会自动初始

化所有这种接口属性;
现在我告诉你可以把这段代码加入以 Global.asax.cs 当中当程序运行时就加载它。如下:
protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    StructureMapConfiguration.Configure();
    ControllerBuilder.Current.SetControllerFactory(new
      StructureMapControllerFactory());
}
最后一行这是我们告诉framework用我们定制的factory来代替默认的。现在你可以把Constructor

初始化的参数去年了吧,让StrutureMap来帮你.

StrutureMap的构造
看到上面代码的第二行了吗?它就是用来构造StrutureMap的。它会构建一个新的StrutureMap 不

需要xml来配置。
public class StructureMapConfiguration
{
    public static void Configure()
    {
        ObjectFactory.Initialize(InitializeStructureMap);
    }
    private static void InitializeStructureMap(IInitializationExpression x)
    {
        x.Scan(y =>
                   {
                      y.Assembly("MvcWithNHibernate.Repositories");
                       y.Assembly("MvcWithNHibernate.Services");
                      y.With<DefaultConventionScanner>();
                   }
            );



http://stackoverflow.com/questions/1183124/how-do-i-mock-httpresponsebase-end
    }
}
你可以学习一下DefaultConventionScanner的用法,这个 scanner 是用来记录哪些接口对应哪些类

来初始化的。比如 UserService 用来初始化IUserService ,UserRepository 来初始化

IUserRepository。
总结:
在这里我们介绍了如何在ASP.NET MVC framework.框架下用StructureMap,我也介绍了怎么样利用

controller factory 来简化你的代码,一般情况下,在一开始就应用 Objectfactory 利用这种方

法可以减少不少代码。在这里只是介绍了在controller 层应用Objectfactory (其他的地方也可

以用了);

我在上面也是简单的写了一些代码,介绍了一些常见的应用,(以下不会翻译了,大致意思是你还

可以控制接口和类对应关系)

 

(这个我已经试过很好用的,还发现了一点就是类的构造参数有接口的它会初始成注册的方法,会优先调用有接口的初始化。但是没有试如果有两个以上有参数的它怎么处理?我想应该按参数最多的那个初始化吧!还没有试,有时间的话就去试一试。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值