• StructureMap依赖注入


    IOC:控制反转,是一种设计模式。一层含义是控制权的转移:由传统的在程序中控制依赖转移到由容器来控制;第二层是依赖注入:将相互依赖的对象分离,在spring配置文件中描述他们的依赖关系。他们的依赖关系只在使用的时候才建立。

    AOP:面向切面,是一种编程思想,OOP的延续。将系统中非核心的业务提取出来,进行单独处理。比如事务、日志和安全等。

    一.配置与注册Services和Repositories

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

     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Text;
     using System.Threading.Tasks;
     using StructureMap;
    
     namespace TYStudioDemo.StructureMap
     {
        public class BootStrapper
        {
            public static void ConfigureStructureMap()
            {
                ObjectFactory.Configure(x =>
                {
                    x.AddRegistry(new TYStudioDemoStructureMapRegistry());
                    x.Scan(scanner =>
                     {
                         scanner.Assembly("TYStudioDemo.Services");
                        scanner.Assembly("TYStudioDemo.Repositories");
                    });
                 });
            }
        }
    }

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

     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Text;
     using System.Data;
     using StructureMap.Configuration.DSL;
     using TYStudioDemo.Models;
     using TYStudioDemo.DTO;
     using TYStudioDemo.Interfaces;
     using TYStudioDemo.Services;
     using TYStudioDemo.Repositories;
    
     namespace TYStudioDemo.StructureMap
     {
         public class TYStudioDemoStructureMapRegistry : Registry
         {
             //注册接口实际使用的实现类
             public TYStudioDemoStructureMapRegistry()
             {
                 SelectConstructor<TYEntities>(() => new TYEntities());
    
                 //Exception Handle
                 For<ITYExceptionService>().Use<TYExceptionService>();
    
                 //Services
                 For(typeof(ISupplierService)).Use(typeof(SupplierService));
    
                //Repositories
                 For(typeof(ISupplierRepository<>)).Use(typeof(SupplierRepository));
                 For(typeof(IProductRepository<>)).Use(typeof(ProductRepository));
             }
         }
     }

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

    二.创建Controller Factory

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

     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Text;
     using System.Threading.Tasks;
     using System.Web.Mvc;
     using StructureMap;
    
     namespace TYStudioDemo.StructureMap
     {
         public class TYStudioDemoStructureMapControllerFactory : DefaultControllerFactory
        {
            protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, System.Type controllerType)
            {
                if (controllerType != null)
                {
                    Controller c = ObjectFactory.GetInstance(controllerType) as Controller;
                    //当返回一个错误页面,View一级异常会被触发
                    c.ActionInvoker = new ErrorHandlingActionInvoker(new HandleErrorAttribute());
                    return c;
                }
                else
                    return null;
            }
        }
    }

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

     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Text;
     using System.Web.Mvc;
    
     namespace TYStudioDemo.StructureMap
     {
         public class ErrorHandlingActionInvoker : ControllerActionInvoker
         {
             private readonly IExceptionFilter filter;
    
             public ErrorHandlingActionInvoker(IExceptionFilter filter)
             {
                 if (filter == null)
                     throw new ArgumentNullException("Exception filter is missing");
    
                 this.filter = filter;
             }
    
             protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDes criptor actionDes criptor)
             {
                 var filterInfo = base.GetFilters(controllerContext, actionDes criptor);
                 filterInfo.ExceptionFilters.Add(this.filter);
                 return filterInfo;
             }
         }
     }

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

    三.配置Global.asax文件

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

     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Web;
     using System.Web.Http;
     using System.Web.Mvc;
     using System.Web.Optimization;
     using System.Web.Routing;
     using TYStudioDemo.StructureMap;
    
     namespace TYStudioDemo.WebUI
     {
         // Note: For instructions on enabling IIS6 or IIS7 classic mode,
         // visit http://go.microsoft.com/?LinkId=9394801
    
         public class MvcApplication : System.Web.HttpApplication
         {
             protected void Application_Start()
             {
                 AreaRegistration.RegisterAllAreas();
    
                 WebApiConfig.Register(GlobalConfiguration.Configuration);
                 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                 RouteConfig.RegisterRoutes(RouteTable.Routes);
                 BundleConfig.RegisterBundles(BundleTable.Bundles);
                 AuthConfig.RegisterAuth();
    
                 //注册StructureMap
                 BootStrapper.ConfigureStructureMap();
    
                 //通过StructureMap返回Controller实例,通过构造器注入
                 ControllerBuilder.Current.SetControllerFactory(new TYStudioDemoStructureMapControllerFactory());
             }
    
             protected void Application_EndRequest(object sender, EventArgs e)
             {
                 TYStudioDemo.Models.TYEntities.Cleanup();
             }
         }
     }

    ok,到此StructureMap的配置就全部完成了,接下来我们该怎么使用它呢。 文章开头已经告诉大家了我们使用Constructor构造器的方式进行依赖注入。 Controller的写法 既然是构造器就要写构造函数了,见下面写法:

     ISupplierService _supplierService;
    
             public SupplierController(ITYExceptionService tyExceptionService,
                                         ISupplierService supplierService)
             {
                 _tyExceptionService = tyExceptionService;
                 _supplierService = supplierService;
    
             }

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

     ISupplierRepository<Supplier> _supplierRepository;
     IProductRepository<Product> _productRepository;
    
             public SupplierService(ISupplierRepository<Supplier> supplierRepotitory,
                                         IProductRepository<Product> productRepository)
             {
                 _supplierRepository = supplierRepotitory;
                 _productRepository = productRepository;
             }

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

    总结:

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

  • 相关阅读:
    .net中使用事务 dodo
    dnn中NULL值的处理 dodo
    通过sql server的作业调度+存储过程来实现系统定时任务的方法 dodo
    使用With...End With dodo
    ASP.NET页面中使用SolpartMenu控件 dodo
    浅解web打印 dodo
    WEB打印大全(转) dodo
    AjaxMethod未定义原因 dodo
    CommandEventArgs.CommandArgument 属性 dodo
    在用VS.NET2003 新建项目时系统提示 autometion服务器无法创建对象 这是什么问题? dodo
  • 原文地址:https://www.cnblogs.com/jobs2/p/3211334.html
Copyright © 2020-2023  润新知