回到目录

IoC是解耦的灵魂,很难想像一个框架中没有IoC会变成什么样子,Lind.DDD里的IoC是通过Unity实现的,由依赖注入(unity)和方法拦截组成(Interception),依赖注入可以通过事前定义好的实现方式去动态建立某个接口的实例,例如,在仓储接口IRepository里,你可以在配置文件中定义它由EF实现,也可以让它由Mongodb实现,而表现出来的结果就是数据的持久化方式的不同。

模块的结构

aaarticlea/png;base64,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" alt="" />

服务定位器ServiceLocator

服务定位器可以帮助我们在不引用程序集的情况下,自动将它进行反射,这对于某些扩展注入的场合,非常有用,也是通过单例模式实现的。

    /// <summary>
/// Represents the Service Locator.
/// </summary>
public sealed class ServiceLocator : IServiceProvider
{
#region Private Fields
private readonly IUnityContainer _container;
#endregion #region Private Static Fields
private static readonly ServiceLocator instance = new ServiceLocator();
#endregion #region Ctor
/// <summary>
/// Initializes a new instance of ServiceLocator class.
/// </summary>
private ServiceLocator()
{
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); if (section == null)
{
var unityConfig = System.AppDomain.CurrentDomain.BaseDirectory + @"\IoC.config";
var fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = unityConfig };
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
section = (UnityConfigurationSection)configuration.GetSection("unity");
} if (section == null)
throw new ArgumentException("请配置unity节点..."); _container = new UnityContainer(); #region 装载config中的类型
section.Configure(_container);
#endregion #region 注册动态类型
LoadDynamicType(_container);
#endregion }
#endregion #region Public Static Properties
/// <summary>
/// Gets the singleton instance of the ServiceLocator class.
/// </summary>
public static ServiceLocator Instance
{
get { return instance; }
} #endregion #region Private Methods
/// <summary>
/// 装载一批动态的类型
/// Author:zhangzhanling
/// Date:2015-04-03
/// </summary>
private void LoadDynamicType(IUnityContainer _container)
{
//unity动态类型注入,各个程序集用,分开,支持*通配符号
string unityDynamicAssembly = System.Configuration.ConfigurationManager.AppSettings["unityDynamicAssembly"];
//是否同时启动数据集缓存策略
string unityCachingDoing = System.Configuration.ConfigurationManager.AppSettings["unityCachingDoing"] ;
InjectionMember[] injectionMembers = new InjectionMember[] { };
if (unityCachingDoing == "")
{
injectionMembers = new InjectionMember[] { new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<CachingBehavior>() };
}
if (!string.IsNullOrWhiteSpace(unityDynamicAssembly))
{
Array.ForEach(unityDynamicAssembly.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), dllName =>
{
var baseDir = AppDomain.CurrentDomain.BaseDirectory;
if (System.Web.HttpContext.Current != null)
{
baseDir += "bin";
}
var files = Directory.GetFiles(baseDir, dllName);
var iTypes = new List<Type>();
foreach (var file in files)
{
var interfaceASM = Assembly.LoadFrom(Path.Combine(baseDir, file));
var types = from t in interfaceASM.GetTypes()
where !string.IsNullOrWhiteSpace(t.Namespace)
select t; foreach (var type in types)
{
if (type.GetInterfaces() != null && type.GetInterfaces().Any())
foreach (var father in type.GetInterfaces())
{
_container.RegisterType(father
, type
, injectionMembers);
}
}
}
}); } } private IEnumerable<ParameterOverride> GetParameterOverrides(object overridedArguments)
{
List<ParameterOverride> overrides = new List<ParameterOverride>(); Type argumentsType = overridedArguments.GetType();
argumentsType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.ToList()
.ForEach(property =>
{
var propertyValue = property.GetValue(overridedArguments, null);
var propertyName = property.Name;
overrides.Add(new ParameterOverride(propertyName, propertyValue));
}); return overrides;
}
#endregion #region Public Methods /// <summary>
/// Gets the service instance with the given type.
/// </summary>
/// <typeparam name="T">The type of the service.</typeparam>
/// <returns>The service instance.</returns>
public T GetService<T>()
{
return _container.Resolve<T>();
}
/// <summary>
/// Gets the service instance with the given type by using the overrided arguments.
/// </summary>
/// <typeparam name="T">The type of the service.</typeparam>
/// <param name="overridedArguments">The overrided arguments.</param>
/// <returns>The service instance.</returns>
public T GetService<T>(object overridedArguments)
{
var overrides = GetParameterOverrides(overridedArguments);
return _container.Resolve<T>(overrides.ToArray());
}
/// <summary>
/// Gets the service instance with the given type by using the overrided arguments.
/// </summary>
/// <param name="serviceType">The type of the service.</param>
/// <param name="overridedArguments">The overrided arguments.</param>
/// <returns>The service instance.</returns>
public object GetService(Type serviceType, object overridedArguments)
{
var overrides = GetParameterOverrides(overridedArguments);
return _container.Resolve(serviceType, overrides.ToArray());
}
#endregion #region IServiceProvider Members
/// <summary>
/// Gets the service instance with the given type.
/// </summary>
/// <param name="serviceType">The type of the service.</param>
/// <returns>The service instance.</returns>
public object GetService(Type serviceType)
{
return _container.Resolve(serviceType);
} #endregion
}

Interception方法拦截

这是AOP面向方面编程里的一个概念,它在方法进行前或者后,对它进行拦截,并注入新的业务逻辑,这种方法一般是接口方法和虚方法,为了方便大家使用,大家抽象了一个基类

    /// <summary>
/// 拦截器抽象基类
/// 实现拦截器的项目需要继承此类,只引用Microsoft.Practices.Unity.Interception.dll程序集
/// </summary>
public abstract class InterceptionBase : IInterceptionBehavior
{
/// <summary>
/// 获取当前行为需要拦截的对象类型接口。
/// </summary>
/// <returns></returns>
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} /// <summary>
///通过实现此方法来拦截调用并执行所需的拦截行为。
/// </summary>
/// <param name="input">调用拦截目标时的输入信息</param>
/// <param name="getNext">通过行为链来获取下一个拦截行为的委托</param>
/// <returns>从拦截目标获得的返回信息</returns>
public abstract IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext); /// <summary>
/// 获取一个<see cref="Boolean"/>值,该值表示当前拦截行为被调用时,是否真的需要执行拦截动作
/// </summary>
public bool WillExecute
{
get { return true; }
}
}

下面是一个异常拦截器的实现

 /// <summary>
/// 拦截器实例,具体拦截器可以自己去建立项目来实现,需要实现IInterceptionBehavior接口
/// 表示用于异常日志记录的拦截行为。
/// </summary>
public class ExceptionLoggingBehavior : InterceptionBase
{ /// <summary>
/// 通过实现此方法来拦截调用并执行所需的拦截行为。
/// </summary>
/// <param name="input">调用拦截目标时的输入信息。</param>
/// <param name="getNext">通过行为链来获取下一个拦截行为的委托。</param>
/// <returns>从拦截目标获得的返回信息。</returns>
public override IMethodReturn Invoke(
IMethodInvocation input,
GetNextInterceptionBehaviorDelegate getNext)
{
//方法执行前
var methodReturn = getNext().Invoke(input, getNext);//原方法被执行
//方法执行后
if (methodReturn.Exception != null)
{
Console.WriteLine(methodReturn.Exception.Message);
Logger.LoggerFactory.Instance.Logger_Error(methodReturn.Exception);
}
return methodReturn;
} }

下面是IOC所需要的配置

<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<!--BEGIN: Unity-->
<unity>
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
<container>
<extension type="Interception" />
<!--被拦截的类型-->
<register type="Lind.DDD.Test.AOP,Lind.DDD.Test" mapTo="Lind.DDD.Test.AOP,Lind.DDD.Test">
<interceptor type="VirtualMethodInterceptor"/>
<!--InterfaceInterceptor,VirtualMethodInterceptor,TransparentProxyInterceptor,这种方法要求被拦截的类继承MarshalByRefObject-->
<interceptionBehavior type="Lind.DDD.IoC.Interception.ExceptionLoggingBehavior,Lind.DDD" />
<!--拦截行为-->
</register>
</container>
</unity> </configuration>

非常感谢各位的阅读!

回到目录

Lind.DDD.IoC依赖注入与面向方面的实现的更多相关文章

  1. Lind.DDD.IoC(大叔推荐)~在服务定位器中引入IoC容器~容器的适配器

    回到目录 关于依赖倒置(DIP) 高层模块不依赖于低层模块的实现,而低层模块依赖于高层模块定义的接口,通俗的讲,就是高层模块定义接口,低层模块负责实现,这在我们实际开发中经常被用到,层与层之间引用,经 ...

  2. Spring.Net控制翻转、依赖注入、面向切面编程

    Spring.Net快速入门:控制翻转.依赖注入.面向切面编程 Spring.Net主要功能: 1.IoC:控制翻转(Inversion of Control)  理解成抽象工厂翻转控制:就是创建对象 ...

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

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

  4. IOC依赖注入简单实例

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

  5. IoC 依赖注入容器 Unity

    原文:IoC 依赖注入容器 Unity IoC 是什么? 在软件工程领域,“控制反转(Inversion of Control,缩写为IoC)”是一种编程技术,表述在面向对象编程中,可描述为在编译时静 ...

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

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

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

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

  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.中文乱码,Jsp\Servlet端的解决办法

    JS.中文乱码,Jsp\Servlet端的解决办法 2010-03-08 15:18:21|  分类: Extjs |  标签:encodeuricomponent  乱码  urldecoder   ...

  2. PHP类的封装和做投票和用进度条显示

    三处理传过来的数据1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// ...

  3. js实用篇之String对象

    概述 String对象是JavaScript原生提供的三个包装对象之一,用来生成字符串的包装对象. var s1 = 'abc'; var s2 = new String('abc'); typeof ...

  4. 搭建LNAMP环境(六)- PHP7源码安装MongoDB和MongoDB拓展

    上一篇:搭建LNAMP环境(五)- PHP7源码安装Redis和Redis拓展 一.安装MongoDB 1.创建mongodb用户组和用户 groupadd mongodb useradd -r -g ...

  5. Box Model,边距折叠,内联和块标签,CSSReset

    一.盒子模型(Box Model) 1.1.宽度测试 1.2.溢出测试 1.3.box-sizing属性 1.4.利用CSS画图 二.边距折叠 2.1.概要 2.2.垂直方向外边距合并计算 三.内联与 ...

  6. UIViewController 生命周期

    创建: 1. alloc 创建对象,分配空间 2.init (initWithNibName) 初始化对象,初始化数据 3.loadView 从nib载入视图 ,通常这一步不需要去干涉.除非你没有使用 ...

  7. SQL Server 2014新特性探秘(2)-SSD Buffer Pool Extension

    简介     SQL Server 2014中另一个非常好的功能是,可以将SSD虚拟成内存的一部分,来供SQL Server数据页缓冲区使用.通过使用SSD来扩展Buffer-Pool,可以使得大量随 ...

  8. SqlServer用sql对表名、字段做修改

    1.重命名表  下例将表 users重命名为 userdd.  EXEC sp_rename 'users', 'userdd'  2. 重命名列  下例将表 userdd中的列 sex 重命名为 s ...

  9. Android自定义属性

    上一篇讲解了Android自定义View,这篇来讲解一下Android自定义属性的使用,让你get新技能.希望我的分享能帮助到大家. 做Android布局是件很享受的事,这得益于他良好的xml方式.使 ...

  10. canvas学习笔记

    html5的新标签:canvas; 作用:标签定义图形,比如图表和其他图像:标签只是图形容器,您必须使用脚本来绘制图形.默认大小:宽300px,高150px; 背景知识:概念最初由苹果公司提出的,用于 ...