回到目录

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. .NET基础知识点

    .NET基础知识点   l  .Net平台  .Net FrameWork框架   l  .Net FrameWork框架提供了一个稳定的运行环境,:来保障我们.Net平台正常的运转   l  两种交 ...

  2. 启动 Apache2.2 的问题

    启动 Apache2.2 的问题: windows不能在本地计算机启动 Apache2.2.有关更多信息,查阅系统事件日志.如果这是非Microsoft服务,请与服务厂商联系,并参考特定服务错误代码1 ...

  3. js中的DOM事件与对象

    概念图 document.getElementById("bb"); 根据id找到bb,只能找一个哦 var aa = document.getElementById(" ...

  4. java,H5微信蓝牙设备开发教程申请设备和添加设备(2)

    转载地址 http://www.vxzsk.com/76.html  申请设备功能 a. 登录公众平台,点击左边功能栏的"添加功能插件",选择"设备功能". b ...

  5. SSIS Data Flow 的 Execution Tree 和 Data Pipeline

    一,Execution Tree 执行树是数据流组件(转换和适配器)基于同步关系所建立的逻辑分组,每一个分组都是一个执行树的开始和结束,也可以将执行树理解为一个缓冲区的开始和结束,即缓冲区的整个生命周 ...

  6. 【Win10 应用开发】扫描和连接Wi-fi网络

    老周今天带大家去“扫雷”了,别当真,是扫描并连接指定无线网络,时尚一点叫Wi-fi. 所以,今天的任务要求你的设备至少有1张无线网卡,目前老周没看到过有N张无线网卡的设备.像笔记本.平板等设备都可以, ...

  7. jQuery源码分析系列(35) : Ajax - jsonp的实现与原理

    ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本 json核心就是:允许用户传递一个callba ...

  8. MVVM框架下 WPF隐藏DataGrid一列

    最近的一个项目,需要在部分用户登录的时候,隐藏DataGrid中的一列,但是常规的绑定不好使,在下面举个例子. XAML部分代码 <Window x:Class="DataGridCo ...

  9. 深入理解DOM事件机制系列第三篇——事件对象

    × 目录 [1]获取 [2]事件类型 [3]事件目标[4]事件代理[5]事件冒泡[6]事件流[7]默认行为 前面的话 在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事 ...

  10. Objective-C精选字符串处理方法

    无论是什么编程语言对字符串的操作是少不了的,对复杂的字符串的分析和操作我们可以用正则表达式来达到我们的目的.简单的字符串处理我们可以借助OC中NSString封装好的字符串处理方法,不过前提是你得了解 ...