博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我心中的核心组件(可插拔的AOP)~第十二回 IoC组件Unity
阅读量:7027 次
发布时间:2019-06-28

本文共 7526 字,大约阅读时间需要 25 分钟。

说在前

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

做在后

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

普通接口和类实现代码

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

 

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

using (IUnityContainer container = new UnityContainer())                {                   container.RegisterType
(); var repository = container.Resolve
(); }

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

using (IUnityContainer container = new UnityContainer())                {                    ConfigurationManager.GetSection("unity");                    UnityConfigurationSection.CurrentSection.Configure(container);                    var repository = container.Resolve
(); }

普通接口和类实现代码

///     /// 基础的数据操作规范    ///     /// 
public interface IRepository
where TEntity : class { ///
/// 添加实体并提交到数据服务器 /// ///
Item to add to repository void Insert(TEntity item); ///
/// 移除实体并提交到数据服务器 /// 如果表存在约束,需要先删除子表信息 /// ///
Item to delete void Delete(TEntity item); ///
/// 修改实体并提交到数据服务器 /// ///
void Update(TEntity item); ///
/// 得到指定的实体集合(延时结果集) /// Get all elements of type {T} in repository /// ///
List of selected elements
IQueryable
GetModel(); ///
/// 根据主键得到实体 /// ///
///
TEntity Find(params object[] id); } public class BackgroundRepository
: IRepository
where T : class {#region IRepository
成员 public virtual void Insert(TEntity item) { OnBeforeSaved(new SavedEventArgs(item, SaveAction.Insert)); Db.Entry
(item); Db.Set
().Add(item); this.SaveChanges(); OnAfterSaved(new SavedEventArgs(item, SaveAction.Insert)); } public virtual void Delete(TEntity item) { OnBeforeSaved(new SavedEventArgs(item, SaveAction.Delete)); Db.Set
().Attach(item); Db.Set
().Remove(item); this.SaveChanges(); OnAfterSaved(new SavedEventArgs(item, SaveAction.Delete)); } public virtual void Update(TEntity item) { OnBeforeSaved(new SavedEventArgs(item, SaveAction.Update)); Db.Set
().Attach(item); Db.Entry(item).State = EntityState.Modified; this.SaveChanges(); OnAfterSaved(new SavedEventArgs(item, SaveAction.Update)); } ///
/// 子类在实现时,可以重写,加一些状态过滤 /// ///
public virtual IQueryable
GetModel() { // return Db.Set
().AsNoTracking();//对象无法自动添加到上下文中,因为它是使用 NoTracking 合并选项检索的。请在定义此关系之前,将该实体显式附加到 ObjectContext。 return Db.Set
();////ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。 } ///
/// 得到原生态结果集 /// ///
public IQueryable
GetEntities() { return Db.Set
(); } #endregion  }

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

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

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

using (IUnityContainer container = new UnityContainer())                {                    ConfigurationManager.GetSection("unity");                    UnityConfigurationSection.CurrentSection.Configure(container);                 var re = container.Resolve
>(); }

下面我们封装一个服务定位器,让它把Unity容器封装一下,方便以后调用它,下面是ServiceLocator的原代码:

///     /// Represents the Service Locator.    ///     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        ///         /// Initializes a new instance of ServiceLocator class.        ///         private ServiceLocator()        {            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");            _container = new UnityContainer();            section.Configure(_container);        }        #endregion        #region Public Static Properties        ///         /// Gets the singleton instance of the ServiceLocator class.        ///         public static ServiceLocator Instance        {            get { return instance; }        }        #endregion        #region Private Methods        private IEnumerable
GetParameterOverrides(object overridedArguments) { List
overrides = new List
(); 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 ///
/// Gets the service instance with the given type. /// ///
The type of the service.
///
The service instance.
public T GetService
() { return _container.Resolve
(); } ///
/// Gets the service instance with the given type by using the overrided arguments. /// ///
The type of the service.
///
The overrided arguments. ///
The service instance.
public T GetService
(object overridedArguments) { var overrides = GetParameterOverrides(overridedArguments); return _container.Resolve
(overrides.ToArray()); } ///
/// Gets the service instance with the given type by using the overrided arguments. /// ///
The type of the service. ///
The overrided arguments. ///
The service instance.
public object GetService(Type serviceType, object overridedArguments) { var overrides = GetParameterOverrides(overridedArguments); return _container.Resolve(serviceType, overrides.ToArray()); } #endregion #region IServiceProvider Members ///
/// Gets the service instance with the given type. /// ///
The type of the service. ///
The service instance.
public object GetService(Type serviceType) { return _container.Resolve(serviceType); } #endregion }

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

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

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

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

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

 

转载地址:http://gfrxl.baihongyu.com/

你可能感兴趣的文章