• StructureMap使用方法(转)


    终于到了题目中的MVC使用StructureMap依赖注入的配置与实现了。在ASP.Net三层架构应用中StructureMap的是最老的IOC/DI工具,也就是依赖注入,很多线上的项目都使用了StructureMap,非常酷的是他是免费的,具体的IOC/DI的设计思想本篇文章不做介绍,想研究可以百度一下,资料很多,哎说道百度想起google一堆泪啊,自从google撤出中国,google是经常的无法访问,很无奈啊很无奈。

     

    依赖注入主要有两种方式:一种是Setter and Getter,一种是构造函数方式。天屹的这套框架使用的后者Constructor构造器的方式。如果你看了前面的文章,就会发现每个Service和Controller中都会有一个构造方法,没错我们就是使用的它们,接下详细的介绍一下StructureMap是怎么在我们的项目中实现依赖注入的。

    mvc-structuremap

    一.配置与注册Services和Repositories

    首先我们告诉StructureMap,我们需要注入的是什么,本系统中需要注册的是Services和Repositories,分别注入到Controller和Service。下面是具体写法,为什么这么写,不必较真,写法是StructureMap提供给我们的,使用就好了。

    查看代码    
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using StructureMap;
    7.  
    8. namespace TYStudioDemo.StructureMap
    9. {
    10.     public class BootStrapper
    11.     {
    12.         public static void ConfigureStructureMap()
    13.         {
    14.             ObjectFactory.Configure(x =>
    15.             {
    16.                 x.AddRegistry(new TYStudioDemoStructureMapRegistry());
    17.  
    18.                 x.Scan(scanner =>
    19.                 {
    20.                     scanner.Assembly("TYStudioDemo.Services");
    21.                     scanner.Assembly("TYStudioDemo.Repositories");
    22.                 });
    23.             });
    24.         }
    25.     }
    26. }

     

    上面的代码告诉了StructureMap去哪里找我们的Service和Repositories。同时TYStudioDemoStructureMapRegistry这个类告诉了StructureMap该用哪个类去实例化我们的接口,下面是TYStudioDemoStructureMapRegistry的代码:

    查看代码    
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Data;
    6. using StructureMap.Configuration.DSL;
    7. using TYStudioDemo.Models;
    8. using TYStudioDemo.DTO;
    9. using TYStudioDemo.Interfaces;
    10. using TYStudioDemo.Services;
    11. using TYStudioDemo.Repositories;
    12.  
    13. namespace TYStudioDemo.StructureMap
    14. {
    15.     public class TYStudioDemoStructureMapRegistry : Registry
    16.     {
    17.         //注册接口实际使用的实现类
    18.         public TYStudioDemoStructureMapRegistry()
    19.         {
    20.             SelectConstructor<TYEntities>(() => new TYEntities());
    21.  
    22.             //Exception Handle
    23.             For<ITYExceptionService>().Use<TYExceptionService>();
    24.  
    25.             //Services
    26.             For(typeof(ISupplierService)).Use(typeof(SupplierService));
    27.  
    28.             //Repositories
    29.             For(typeof(ISupplierRepository<>)).Use(typeof(SupplierRepository));
    30.             For(typeof(IProductRepository<>)).Use(typeof(ProductRepository));
    31.         }
    32.     }
    33. }

    现在我们已经配置了StructureMap并且注册了Service和Repository,接下来该告诉系统去使用StructureMap去实例化我们的Controller。

    二.创建Controller Factory

    既然使用了依赖注入,Controller的实例化当然不能再用系统本身的了,所以我们需要创建一个ControllerFactory:TYStudioDemoStructureMapControllerFactory。

    查看代码    
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Web.Mvc;
    7. using StructureMap;
    8.  
    9. namespace TYStudioDemo.StructureMap
    10. {
    11.     public class TYStudioDemoStructureMapControllerFactory : DefaultControllerFactory
    12.     {
    13.         protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, System.Type controllerType)
    14.         {
    15.             if (controllerType != null)
    16.             {
    17.                 Controller c = ObjectFactory.GetInstance(controllerType) as Controller;
    18.  
    19.                 //当返回一个错误页面,View一级异常会被触发
    20.                 c.ActionInvoker = new ErrorHandlingActionInvoker(new HandleErrorAttribute());
    21.                 return c;
    22.             }
    23.             else
    24.                 return null;
    25.         }
    26.     }
    27. }

     

    TYStudioDemoStructureMapControllerFactory继承自DefaultControllerFactory,DefaultControllerFactory是MVC默认的Controller Factory,然后重新器获得Controller实例的方法,由StructureMap的ObjectFactory来创建实例,StructureMap会帮我们把Controller构造函数中的参数实例化。

    上面的ErrorHandlingActionInvoker方法:

    查看代码    
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Web.Mvc;
    6.  
    7. namespace TYStudioDemo.StructureMap
    8. {
    9.     public class ErrorHandlingActionInvoker : ControllerActionInvoker
    10.     {
    11.         private readonly IExceptionFilter filter;
    12.  
    13.         public ErrorHandlingActionInvoker(IExceptionFilter filter)
    14.         {
    15.             if (filter == null)
    16.                 throw new ArgumentNullException("Exception filter is missing");
    17.  
    18.             this.filter = filter;
    19.         }
    20.  
    21.         protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    22.         {
    23.             var filterInfo = base.GetFilters(controllerContext, actionDescriptor);
    24.             filterInfo.ExceptionFilters.Add(this.filter);
    25.             return filterInfo;
    26.         }
    27.     }
    28. }

    Controller Factory创建ok。但是这样系统是不会使用我们自己的Controller Factory的,所以需要通知一下MVC系统。

    三.配置Global.asax文件

    在Application_Start()方法中也就是项目启动的时候注册StructureMap并通知系统使用我们自己的Controller Factory进行实例化Controller。

    查看代码    
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Web;
    5. using System.Web.Http;
    6. using System.Web.Mvc;
    7. using System.Web.Optimization;
    8. using System.Web.Routing;
    9. using TYStudioDemo.StructureMap;
    10.  
    11. namespace TYStudioDemo.WebUI
    12. {
    13.     // Note: For instructions on enabling IIS6 or IIS7 classic mode,
    14.     // visit http://go.microsoft.com/?LinkId=9394801
    15.  
    16.     public class MvcApplication : System.Web.HttpApplication
    17.     {
    18.         protected void Application_Start()
    19.         {
    20.             AreaRegistration.RegisterAllAreas();
    21.  
    22.             WebApiConfig.Register(GlobalConfiguration.Configuration);
    23.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    24.             RouteConfig.RegisterRoutes(RouteTable.Routes);
    25.             BundleConfig.RegisterBundles(BundleTable.Bundles);
    26.             AuthConfig.RegisterAuth();
    27.  
    28.             //注册StructureMap
    29.             BootStrapper.ConfigureStructureMap();
    30.  
    31.             //通过StructureMap返回Controller实例,通过构造器注入
    32.             ControllerBuilder.Current.SetControllerFactory(new TYStudioDemoStructureMapControllerFactory());
    33.         }
    34.  
    35.         protected void Application_EndRequest(object sender, EventArgs e)
    36.         {
    37.             TYStudioDemo.Models.TYEntities.Cleanup();
    38.         }
    39.     }
    40. }

    ok,到此StructureMap的配置就全部完成了,接下来我们该怎么使用它呢。

    文章开头已经告诉大家了我们使用Constructor构造器的方式进行依赖注入。

    四.Controller的写法

    既然是构造器就要写构造函数了,见下面写法:

    查看代码    
    1. ISupplierService _supplierService;
    2.  
    3. public SupplierController(ITYExceptionService tyExceptionService,
    4.                             ISupplierService supplierService)
    5. {
    6.     _tyExceptionService = tyExceptionService;
    7.     _supplierService = supplierService;
    8.  
    9. }

    在构造方法中加入我们要注入的Service接口,然后StructureMap就会根据上面TYStudioDemoStructureMapRegistry的配置去创建我们需要实例化的service对象了。

    同样向Service中注入Repository的写法是一样的:

    查看代码    
    1. ISupplierRepository<Supplier> _supplierRepository;
    2. IProductRepository<Product> _productRepository;
    3.  
    4. public SupplierService(ISupplierRepository<Supplier> supplierRepotitory,
    5.                             IProductRepository<Product> productRepository)
    6. {
    7.     _supplierRepository = supplierRepotitory;
    8.     _productRepository = productRepository;
    9. }

    至此StructureMap配置与使用就全部完成了。

    总结:

    我们发现,我们的参数都是接口类型了,这样的好处就是将来对ISupplierService的实现不一样了,我们只需要重写写一个ISupplierService的实现了,并修改TYStudioDemoStructureMapRegistry使ISupplierService使用新的实现类,就可以了。因为我们使用的都是接口所以方法和参数都是固定的,所以呢~~ Controller中不用修改任何代码,同理Service也是一样的。这样就充分的降低了代码之间的耦合度。

    下篇文章将介绍使用Enterprise Library 5.0 实现异常与日志的处理。

     

    转自:http://www.tystudio.net/2013/04/06/mvc-structuremap-config/

  • 相关阅读:
    寒假作业1
    秋季学习总结
    记叙在人生路上对你影响最大的三位老师
    2019年春季学期第二周作业
    币值转换
    第九周作业
    第八周作业
    第七周作业
    第六周作业
    第五周作业
  • 原文地址:https://www.cnblogs.com/qianyaoyuan/p/3552138.html
Copyright © 2020-2023  润新知