使用Unity的好处网上有很多,百度一下即可

这里引用了一篇关于面向接口编程的好处的文章作为引申:https://blog.csdn.net/Cyy19970527/article/details/83177996

在MVC中使用Unity

需要引用Unity包,我安装的版本为 Unity-4.0.1

尽管现在Unity最新版本已经更新到5.11.2了,但是在使用配置文件注入的时候,总是报以下错误,

百度查找到一篇文章说是版本问题: https://blog.csdn.net/weixin_34124577/article/details/93533679

接下来直接上测试代码:项目结构使用简单的三层结构

DAL层

namespace DAL
{
//声明一个接口层,获取名称
public interface IADao
{
string GetName();
}
} //实现1
public class A1Dao : IADao
{
public string GetName()
{
return "我叫A1";
}
} //实现2
public class A2Dao : IADao
{
public string GetName()
{
return "我叫A2";
}
}

BLL层

namespace BLL
{
//声明一个Bll层接口
public interface IA
{
string GetName();
}
} //实现1
public class A1 : IA
{
IADao _a1; //构造函数注入
[InjectionConstructor]
public A1(IADao a1)
{
_a1 = a1;
} public string GetName()
{
return _a1.GetName();
}
} //实现2
public class A2 : IA
{
//属性注入 "a2dao" 是区分两个不同实现的标识,在配置文件中声明该名称
[Dependency("a2dao")]
public DAL.IADao _a1 { get; set; } public string GetName()
{
return _a1.GetName();
}
}

在控制器中调用

public class HomeController : Controller
{
//通过属性注入
[Dependency("a2")]
public IA _a2 { get; set; } private IA _ia;

//构造函数注入
[InjectionConstructor]
public HomeController(IA ia) //如果都通过构造函数注入,则通过该方式区分([Dependency("a1")]IA a1,[Dependency("a2")]IA a2)
{
_ia = ia;
} public ActionResult Index()
{
ViewBag.Name = _ia.GetName(); //通过构造函数注入获取 ViewBag.A2Name = _a2.GetName(); //通过属性注入获取 return View();
}
}

显示结果:

接下来说如何配置

1,首先要引用Unity插件

2,然后在App_Start 文件夹下创建一个注册配置类UnityConfig (引用插件的时候会自动创建,自定义也可以),用来注册配置文件Unity.config中的配置,

   /// <summary>
/// 配置文件公用类
/// </summary>
public class UnityConfig
{
/// <summary>
/// MVC注入 在全局方法中调用该方法,实现全局注册
/// </summary>
public static void Start()
{
var container = ApiContainer.GetUnityContainer();
RegisterTypes(container); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); //MVC注入
} /// <summary>
/// 使用配置文件注册
/// </summary>
/// <param name="container"></param>
private static void RegisterTypes(IUnityContainer container)
{
//使用单独的Unity.config配置文件
var filepath = HttpRuntime.AppDomainAppPath;
var context = HttpContext.Current;
if (context != null)
{
filepath = context.Server.MapPath("~/");
}
var getfile = filepath + "Unity.config";
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = getfile };
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
var unitySection = (UnityConfigurationSection)configuration.GetSection("unity");
container.LoadConfiguration(unitySection, "defaultContainer"); //在App.config或者Web.Config中配置
//UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
//container.LoadConfiguration(section, "defaultContainer"); //或者section.Configure(container, "defaultContainer");
}
}

3,然后同样在App_Start 文件夹下创建一个UnityDependencyResolver 类,同时实现接口:IDependencyResolver

 /// <summary>
/// 用于自动实现对象类
/// </summary>
public class UnityDependencyResolver : IDependencyResolver
{
IUnityContainer container;
public UnityDependencyResolver(IUnityContainer container)
{
this.container = container;
} public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch
{
return null;
}
} public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch
{
return new List<object>();
}
}
}

4,写一个Unity公共类,也可以将该类集成到项目中

    /// <summary>
/// Unity公共类
/// </summary>
public class ApiContainer
{
private readonly static IUnityContainer _container = null; /// <summary>
/// 初始化容器
/// </summary>
/// <returns></returns>
static ApiContainer()
{
//新建容器构建器,用于注册组件和服务
_container = new UnityContainer();
} /// <summary>
/// 对外开放函数 获取Unity容器
/// </summary>
/// <returns></returns>
public static IUnityContainer GetUnityContainer()
{
return _container;
} /// <summary>
/// 获取实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T GetServer<T>()
{
return _container.Resolve<T>();
} /// <summary>
/// 可以根据ConfigName获取实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ConfigName">配置文件中指定的文字</param>
/// <returns></returns>
public static T GetServer<T>(string ConfigName)
{
return _container.Resolve<T>(ConfigName);
} /// <summary>
/// 返回构结函数带参数
/// </summary>
/// <typeparam name="T">依赖对象</typeparam>
/// <param name="ConfigName">配置文件中指定的文字(没写会报异常)</param>
/// <param name="parameterList">参数集合(参数名,参数值)</param>
/// <returns></returns>
public static T GetServer<T>(Dictionary<string, object> parameterList)
{
var list = new ParameterOverrides();
foreach (KeyValuePair<string, object> item in parameterList)
{
list.Add(item.Key, item.Value);
}
return _container.Resolve<T>(list.OnType<T>());
} }

5,在项目根目录下创建一个 Unity.config 文件,配置如下

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity>
<containers>
<container name="defaultContainer">
<register type="BLL.IA,BLL" mapTo="BLL.A1, BLL"/>
<register type="BLL.IA,BLL" mapTo="BLL.A2, BLL" name="a2" />
<register type="DAL.IADao,DAL" mapTo="DAL.A1Dao, DAL"/>
<register type="DAL.IADao,DAL" mapTo="DAL.A2Dao, DAL" name="a2dao"/>
</container>
</containers>
</unity>
</configuration>

6,在全局中注册 Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles); UnityConfig.Start(); //全局注册 可通过构造函数or属性调用
}
}

到此全部结束

如果要在 WebAPI中使用Unity,则除了引用Unity插件,还要引用 Unity.WebApI 插件,引用版本如下:

然后需要调整一处地方,将MVC的注入方式换成WebAPI的注入方式,如下:

using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.WebApi;
using System.Web.Http;
namespace API.App_Start
{
/// <summary>
/// 配置文件公用类
/// </summary>
public class UnityConfig
{
public static void Start()
{
//DependencyResolver.SetResolver(new UnityDependencyResolver(container));   //MVC注入方式
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(GetConfiguredContainer()); //API注入方式
}
}
}

另外需要去掉上边代码中的 UnityDependencyResolver : IDependencyResolver 实现。API的不需要实现如下接口, 去掉如下图的实现。

其他的地方都一样。

参考文章:

https://www.cnblogs.com/qqlin/archive/2012/10/18/2720828.html

https://blog.csdn.net/hezheqiang/article/details/80255280

Ioc依赖注入:Unity4.0.1 在项目中的应用 (MVC和API)的更多相关文章

  1. 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入

    系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...

  2. Spring学习-spring核心机制-IOC依赖注入

    转载自:http://www.cnblogs.com/chenssy/archive/2012/11/11/2765266.html 今天复习一下spring两大特性之一:IOC依赖注入,看了一下大佬 ...

  3. IOC依赖注入简单实例

    转自:http://hi.baidu.com/xyz136299110/item/a32be4269e9d0c55c38d59e6 相信大家看过相当多的IOC依赖注入的例子. 但大家在没有明白原理的情 ...

  4. ASP.NET Core2使用Autofac实现IOC依赖注入竟然能如此的优雅简便

    初识ASP.NET Core的小伙伴一定会发现,其几乎所有的项目依赖都是通过依赖注入方式进行链式串通的.这是因为其使用了依赖注入 (DI) 的软件设计模式,代码的设计是遵循着“高内聚.低耦合”的原则, ...

  5. ASP.NET MVC IOC依赖注入之Autofac系列(二)- WebForm当中应用

    上一章主要介绍了Autofac在MVC当中的具体应用,本章将继续简单的介绍下Autofac在普通的WebForm当中的使用. PS:目前本人还不知道WebForm页面的构造函数要如何注入,以下在Web ...

  6. ASP.NET MVC IOC依赖注入之Autofac系列(一)- MVC当中应用

    话不多说,直入主题看我们的解决方案结构: 分别对上面的工程进行简单的说明: 1.TianYa.DotNetShare.Model:为demo的实体层 2.TianYa.DotNetShare.Repo ...

  7. ASP.NET Core2使用Autofac实现IOC依赖注入竟然能如此的优雅简便(转载)

    原文地址:https://www.cnblogs.com/Andre/p/9604759.html 初识ASP.NET Core的小伙伴一定会发现,其几乎所有的项目依赖都是通过依赖注入方式进行链式串通 ...

  8. springboot启动流程(九)ioc依赖注入

    所有文章 https://www.cnblogs.com/lay2017/p/11478237.html 正文 在前面的几篇文章中,我们多次提到这么一个转化过程: Bean配置 --> Bean ...

  9. Spring-DI控制反转和IOC依赖注入

    Spring-DI控制反转和IOC依赖注入 DI控制反转实例 IDEAJ自动导入Spring框架 创建UserDao.java接口 public interface UserDao { public ...

随机推荐

  1. js—求数组中的最大最小值

    参考链接:https://www.w3cplus.com/javascript/calculate-the-max-min-value-from-an-array.html Math.min.appl ...

  2. clr via c# 程序集加载和反射集(一)

    1,程序集加载---弱的程序集可以加载强签名的程序集,但是不可相反.否则引用会报错!(但是,反射是没问题的) //获取当前类的Assembly Assembly.GetEntryAssembly() ...

  3. SAP 如何看某个TR是否传入了Q或者P系统?

    SAP 如何看某个TR是否传入了Q或者P系统? 两种方式可以查询. 1)进入Q系统或者P系统.SE16,看表TPALOG, 输入请求号码, 执行,看记录里的字段TPSTAT_KEY是否为空,如果不为空 ...

  4. 微信小程序入门笔记-审核上线(5)

    1.点击上传 2.填写版本号.备注 3.https://mp.weixin.qq.com/回到微信公众平台,点击版本管理就可以看到开发版本 4.点击提交审核(提交之前填写小程序基本资料,才可提交审核) ...

  5. Linux上安装软件

    Linux发行版的两大系列 debian:代表的比如Ubuntu,软件包管理工具apt.apt-get.dpkg,软件包名.deb redhat:代表的比如CentOS(所以在VMware上安装Cen ...

  6. Blazor client-side + webapi (.net core 3.1) 添加jwt验证流程(非host)第一步

    第一步,设置并检查CROS跨域请求 因为我们并不打算将Blazor 由webapi来进行host,所以Blazor和api将是两个域名,这样操作即方便以后单独使用Blazor来写前端,但后端采用已有或 ...

  7. 【转】JS 的 new 到底是干什么的?

    原文:https://zhuanlan.zhihu.com/p/23987456?refer=study-fe 大部分讲 new 的文章会从面向对象的思路讲起,但是我始终认为,在解释一个事物的时候,不 ...

  8. 展讯平台uboot启动流程

    启动流程 1. Stage1 start.S代码结构 u-boot的stage1代码通常放在start.S文件中,用汇编语言,主要实现功能如下:  (1) 定义入口: 该工作通过修改连接器脚本来完成. ...

  9. maven 新建站点

    站点建立步骤启动eclipse_sts--->新建项目--->搜索maven -->选择maven-archetype-webapp 红色错误配置新建项目完成后--->inde ...

  10. XSS跨站测试代码

    '><script>alert(document.cookie)</script>='><script>alert(document.cookie)&l ...