我心中的核心组件(可插拔的AOP)~第十二回 IoC组件Unity

简介:

说在前

Ioc组件有很多,之前也介绍过autofac,castle等,今天再来说一下在微软Nlayer DDD架构里使用的unity组件,今天主要说一下依靠注入,如果希望看拦截的用法,可以阅读这篇文章第十三回 实现AOP的拦截组件Unity.Interception

做在后

unity的用法主要说一下接口注入方法,它包括了程序中注入和配置文件注入,而接口注入还分为普通接口注入和泛型接口注入,下面分别来说一下:

普通接口和类实现代码

  public interface IUser
    {
        IQueryable<WebManageUsers> GetEntities();
    }
   public class UserRepository : BackgroundRepository<WebManageUsers>, IUser
    {
        public IQueryable<WebManageUsers> GetEntities()
        {
            return this.GetModel();
        }
    }

普通接口注入,程序中的注入

   using (IUnityContainer container = new UnityContainer())
                {
                   container.RegisterType<IUser, DataTest.UserRepository>();
                    var repository = container.Resolve<IUser>();
                }

普通接口注入,配置文件中的注入

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <container>
      <register  type="EntityTest.IUser,EntityTest" mapTo="DataTest.UserRepository, DataTest" />
       </container>
  </unity>
 using (IUnityContainer container = new UnityContainer())
                {
                    ConfigurationManager.GetSection("unity");
                    UnityConfigurationSection.CurrentSection.Configure(container);
                    var repository = container.Resolve<IUser>();
                }

普通接口和类实现代码

 /// <summary>
    /// 基础的数据操作规范
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public interface IRepository<TEntity>
           where TEntity : class
    {
        /// <summary>
        /// 添加实体并提交到数据服务器
        /// </summary>
        /// <param name="item">Item to add to repository</param>
        void Insert(TEntity item);

        /// <summary>
        /// 移除实体并提交到数据服务器
        /// 如果表存在约束,需要先删除子表信息
        /// </summary>
        /// <param name="item">Item to delete</param>
        void Delete(TEntity item);

        /// <summary>
        /// 修改实体并提交到数据服务器
        /// </summary>
        /// <param name="item"></param>
        void Update(TEntity item);

        /// <summary>
        /// 得到指定的实体集合(延时结果集)
        /// Get all elements of type {T} in repository
        /// </summary>
        /// <returns>List of selected elements</returns>
        IQueryable<TEntity> GetModel();

        /// <summary>
        /// 根据主键得到实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        TEntity Find(params object[] id);
    }
    public class BackgroundRepository<T> : IRepository<T> where T : class
    {
#region IRepository<TEntity> 成员

        public virtual void Insert(TEntity item)
        {
            OnBeforeSaved(new SavedEventArgs(item, SaveAction.Insert));
            Db.Entry<TEntity>(item);
            Db.Set<TEntity>().Add(item);
            this.SaveChanges();
            OnAfterSaved(new SavedEventArgs(item, SaveAction.Insert));
        }

        public virtual void Delete(TEntity item)
        {
            OnBeforeSaved(new SavedEventArgs(item, SaveAction.Delete));
            Db.Set<TEntity>().Attach(item);
            Db.Set<TEntity>().Remove(item);
            this.SaveChanges();
            OnAfterSaved(new SavedEventArgs(item, SaveAction.Delete));
        }

        public virtual void Update(TEntity item)
        {
            OnBeforeSaved(new SavedEventArgs(item, SaveAction.Update));
            Db.Set<TEntity>().Attach(item);
            Db.Entry(item).State = EntityState.Modified;
            this.SaveChanges();
            OnAfterSaved(new SavedEventArgs(item, SaveAction.Update));
        }

        /// <summary>
        /// 子类在实现时,可以重写,加一些状态过滤
        /// </summary>
        /// <returns></returns>
        public virtual IQueryable<TEntity> GetModel()
        {
            //  return Db.Set<TEntity>().AsNoTracking();//对象无法自动添加到上下文中,因为它是使用 NoTracking 合并选项检索的。请在定义此关系之前,将该实体显式附加到 ObjectContext。
            return Db.Set<TEntity>();////ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。
        }
        /// <summary>
        /// 得到原生态结果集
        /// </summary>
        /// <returns></returns>
        public IQueryable<TEntity> GetEntities()
        {
            return Db.Set<TEntity>();
        }
        #endregion

泛型接口注入,程序中的注入

  using (IUnityContainer container = new UnityContainer())
                {
                   container.RegisterType<IRepository<User>, BackgroundRepository<User>>();
                    var re = container.Resolve<IRepository<User>>();
                }

泛型接口注入,配置文件中的注入

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <container>
         <register  type="IRepository.Core.IRepository`1,IRepository.Core" mapTo="DataTest.BackgroundRepository`1, DataTest" />
    </container>
  </unity>
  using (IUnityContainer container = new UnityContainer())
                {
                    ConfigurationManager.GetSection("unity");
                    UnityConfigurationSection.CurrentSection.Configure(container);
                 var re = container.Resolve<IRepository<User>>();
                }

下面我们封装一个服务定位器,让它把Unity容器封装一下,方便以后调用它,下面是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");
            _container = new UnityContainer();
            section.Configure(_container);
        }
        #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
        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
    }

下面再去使用unity时就方便多了,呵呵,看代码:

 var model = ServiceLocator.Instance.GetService<IExtensionRepository<WebManageUsers>>().GetModel().ToList();

而使用ServiceLocator还有一个好处,就是不需要使用"实现的程序集",只要把"实现的程序集"和它的相关依赖的程序集一起复制到WEB项目的BIN目录即可,服务定位器会自己去定位的.

好了,讲到这里也就差不多了,需要注意的是,如果你在项目中进行注入时,需要先注入的实现类所在的程序集也引入进来,否则也是不可以resolve出来对象的,而对于业务层(领域)层来说,不需要关心底层

的实现技术,即不需要引用实现类的程序集,而在业务层引用接口程序集即可.

本文转自博客园张占岭(仓储大叔)的博客,原文链接:我心中的核心组件(可插拔的AOP)~第十二回 IoC组件Unity,如需转载请自行联系原博主。

目录
相关文章
|
8月前
|
XML 监控 Java
注解IOC&AOP
扫描类下的注解,哪些包下的类需要使用IOC注解
68 0
|
12天前
|
安全 Java 开发者
在Spring框架中,IoC和AOP是如何实现的?
【4月更文挑战第30天】在Spring框架中,IoC和AOP是如何实现的?
22 0
|
3月前
|
Java 测试技术 开发者
探究 Spring Boot 的核心:IOC 和 AOP
Spring Boot 作为一种简化 Spring 应用开发的工具,继承了 Spring 框架的核心概念,其中最重要的是控制反转(IOC)和面向切面编程(AOP)。它们是 Spring 框架的基础,同时也深深植根于 Spring Boot 中。本文将讨论 IOC 和 AOP 的概念以及它们在 Spring Boot 中的应用。
66 4
|
8月前
|
XML Java 数据格式
【Spring】全面讲解IOC、AOP、注入方式、bean的生命周期、aop通知应用 spring与web容器整合
Spring是一个开源的轻量级Java应用开发框架,它提供了一种简单、高效、灵活的方式来构建企业级应用程序。Spring框架的核心特点是依赖注入(Dependency Injection)和面向切面编程(Aspect-Oriented Programming),它通过一组模块化的组件提供全面的支持,使开发人员能够快速搭建可扩展、可维护的应用。
|
5月前
|
编解码 前端开发 人机交互
【Unity 3D】UI系统中UGUI各个组件的详细讲解(附源码 超详细)
【Unity 3D】UI系统中UGUI各个组件的详细讲解(附源码 超详细)
96 0
|
5月前
|
C# 图形学
【Unity 3D】游戏对象、添加删除获取组件、预制体Prefabs简介
【Unity 3D】游戏对象、添加删除获取组件、预制体Prefabs简介
87 0
|
5月前
|
安全 Java 数据库连接
Spring框架:IoC容器、AOP、事务管理等知识讲解梳理
Spring框架:IoC容器、AOP、事务管理等知识讲解梳理
58 1
|
5月前
|
设计模式 Java 程序员
深入理解spring的两大特性 ioc 和aop
深入理解spring的两大特性 ioc 和aop
61 0
|
5月前
|
编译器 图形学
Unity用脚本获取物体和组件(下)
Unity用脚本获取物体和组件(下)
104 0
|
5月前
|
图形学
Unity 用脚本获取物体和组件(上)
Unity 用脚本获取物体和组件(上)
134 0