Unity在WPF中的应用

1. 本文的实现类继承于IRepository

 1 using System;
 2 using System.Linq;
 3 using System.Linq.Expressions;
 4 using Zhang.Test.ELUnityUtility;
 5 
 6 namespace Zhang.Test.IDataLayer
 7 {
 8     [UnityInjection("First", Name = "GenericRepository", ConfigFile = "Zhang.Test.exe.config")]
 9     public interface IRepository
10     {
11         IQueryable<T> GetEntitiesByCondition<T>(Expression<Func<T, bool>> predicate = null) where T : class;
12         T GetEntityByCondition<T>(Expression<Func<T, bool>> predicate) where T : class;
13         T GetEntityByPK<T>(object key) where T : class;
14         IQueryable<T> GetEntitiesBySqlCommond<T>(String sqlCommond);
15         void Insert<T>(T entity) where T : class;
16         //void BatchInsert<T>(IEnumerable<T> entities);
17         void Update<T>(T entity) where T : class;
18         void Delete<T>(T entity) where T : class;
19         //void BatchDelete<T>(IEnumerable<T> entities);
20         int SaveChanges();
21     }
22 }

2. 实现效果

通过调用接口的实现类可以实现调用其中的方法,如下:

class Repository:IRepository
{
     public Insert<T>(T entity) where T: class
    {
          Console.WriteLine("Insert method");  
    }      
    ........
}

 

3. 通过实例化Repository就可以调用其中的方法,但是AOP的作用是向在调用方法之前或之后注入其他代码,使它可以在不动Repository的基础上重用它。  

4. 调用处理方法

我们先定义一段处理方法的代码,Unity规定它是ICallHandler的一个实现:

using System;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace Zhang.Test.DataLayer
{
    [ConfigurationElementType(typeof (CustomCallHandlerData))]
    public class CallHandler : ICallHandler
    {
        #region ICallHandler 成员

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            if (input == null) throw new ArgumentNullException("input");
            if (getNext == null) throw new ArgumentNullException("getNext");
            //Console.WriteLine("begin....");
            var result = getNext()(input, getNext);
            //Console.WriteLine("end....");
            return result;
        }

        public int Order { get; set; }

        #endregion
    }

    
}

5. OK, 下面我们怎么把CallHandler和IRepository关联起来,大体有两种方法:

  • 通过代码直接关联,这种方法比较直接,首先,先建一个Attribute:
[AttributeUsage(AttributeTargets.Method)]
    public class CallHandlerAttribute : HandlerAttribute
    {
        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new CallHandler();
        }
    }

然后在IRepository的实现中使用如下代码:

[CallHandler]
class OutputImplement1 : IRepository
{
int SaveChanges()
}

这里靠此Attribute就将二者关联了起来

现在执行处写:

var container1 = new UnityContainer()
    .AddNewExtension<Interception>()
    .RegisterType<IOutput, OutputImplement1>();//声明UnityContainer并注册IOutput
 container1
     .Configure<Interception>()
     .SetInterceptorFor<IOutput>(new InterfaceInterceptor());
 var op1 = container1.Resolve<IOutput>();
 op1.SaveChanges();//调用

  

  • 用配置文件处理

       如果用配置文件的话就不需要使用Attribute了,所以实现的类如下:

 

class OutputImplement2 : IRepository
{ 
    int SaveChanges()
}

这里我们不需要属性来标记了,而使用配置文件,我们建一个Unity.xml的配置文件,

  <!--Unity configuration begin-->
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">

    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration ">
    </sectionExtension>
    <!--<assembly name="Zhang.Test.DataLayer" />
    <assembly name="Zhang.Test.IDataLayer" />-->
    <container name="First">
      <extension type="Interception" />
      <!--<register type="Zhang.Test.IDataLayer.ISample`1,Zhang.Test.IDataLayer"
                mapTo="Zhang.Test.DataLayer.SampleIocDAL,Zhang.Test.DataLayer" name="ISample">
        <interceptor type="InterfaceInterceptor" />
        <policyInjection />
      </register>-->
      <register type="Zhang.Test.IDataLayer.IRepository,Zhang.Test.IDataLayer"
                mapTo="Zhang.Test.DataLayer.GenericRepository,Zhang.Test.DataLayer" name="GenericRepository">
      </register>
      <!--<interceptors>
        <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework">
          <parameters>
            <parameter value="C:\Temp\LogOutput.txt"/>
          </parameters>
        </interceptor>
      </interceptors>-->
    </container>

  </unity>

最后我们来执行一下,要比第一种复杂一点:

 

using System;
using System.Linq;
using System.Linq.Expressions;
using Zhang.Test.ELUnityUtility;
using Zhang.Test.IDataLayer;
using Zhang.Test.Common;
using System.Collections.Generic;
using Zhang.Test.DataExchange;
using Zhang.Test.DataTransferObject;


namespace Zhang.Test.BusinessLayer
{
    public class BaseBL
    {
        private readonly IRepository repository;

        public BaseBL()
        {
            string startTime = LoggerHelper.StartEvent("constructor");

            try
            {
                //Initialize repository class by Unity
                repository = typeof (IRepository).Resolve<IRepository>() as IRepository;
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw e;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }
        }

        public IQueryable<T> QueryEntitiesByCondition<T>(Expression<Func<T, bool>> predicate = null) where T : class
        {
            string startTime = LoggerHelper.StartEvent();

            IQueryable<T> result = null;
            try
            {
                if (null != repository)
                {
                    result = repository.GetEntitiesByCondition(predicate);
                }
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }

            return result;
        }

        /// <summary>
        ///     Query first entity by filter
        /// </summary>
        /// <param name="predicate">Lamda expression</param>
        /// <returns>Entity</returns>
        public T QueryEntityByCondition<T>(Expression<Func<T, bool>> predicate) where T : class
        {
            string startTime = LoggerHelper.StartEvent();

            T reslult = null;
            try
            {
                if (null != repository && null != predicate)
                {
                    reslult = repository.GetEntityByCondition(predicate);
                }
            }
            catch (Exception e) //
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }

            return reslult;
        }

        /// <summary>
        ///     Query a entity by primary key
        /// </summary>
        /// <param name="key">primary key of entity</param>
        /// <returns>Entity</returns>
        public T QueryEntityByPK<T>(object key) where T : class
        {
            string startTime = LoggerHelper.StartEvent();

            T reslult = null;
            try
            {
                if (null != repository && null != key)
                {
                    reslult = repository.GetEntityByPK<T>(key);
                }
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }

            return reslult;
        }

        /// <summary>
        ///     Query entity set by sqlcommond, property of entity should be match with sqlcommond
        /// </summary>
        /// <param name="sqlCommond">SQL</param>
        /// <returns>Entity set</returns>
        public IQueryable<T> QueryEntitiesBySqlCommond<T>(String sqlCommond)
        {
            string startTime = LoggerHelper.StartEvent();

            IQueryable<T> result = null;
            try
            {
                Dictionary<string, Object> msg = new Dictionary<string, object>();
                msg.Add("QueryEntitiesBySqlCommond", sqlCommond);
                LoggerHelper.Info(msg);
                if (null != repository && !string.IsNullOrEmpty(sqlCommond))
                {
                    result = repository.GetEntitiesBySqlCommond<T>(sqlCommond);
                }
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }
            
            return result;
        }

        /// <summary>
        ///     Query entity set by sqlcommond, property of entity should be match with sqlcommond
        /// </summary>
        /// <param name="sqlCommond">SQL</param>
        /// <returns>Entity set</returns>
        public string QueryValueBySqlCommond(String sqlCommond)
        {
            string startTime = LoggerHelper.StartEvent();

            //IQueryable<string> result = null;
            try
            {
                Dictionary<string, Object> msg = new Dictionary<string, object>();
                msg.Add("QueryValueBySqlCommond", sqlCommond);
                LoggerHelper.Info(msg);

                if (null != repository && !string.IsNullOrEmpty(sqlCommond))
                {
                    return QueryEntitiesBySqlCommond<string>(sqlCommond).FirstOrDefault();
                    /*result = QueryEntitiesBySqlCommond<string>(sqlCommond);
                    if (result != null && result.ToList().Count > 0)
                    {
                        return result.ToList()[0];
                    }*/
                }
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }
            
            return "";
        }

        /// <summary>
        ///     Query  by sqlcommond, property of entity should be match with sqlcommond
        /// </summary>
        /// <param name="sqlCommond">SQL</param>
        /// <returns>num</returns>
        public int QueryIntValueBySqlCommond(String sqlCommond)
        {
            string startTime = LoggerHelper.StartEvent();

            //IQueryable<int?> result = null;
            try
            {
                Dictionary<string, Object> msg = new Dictionary<string, object>();
                msg.Add("QueryIntValueBySqlCommond", sqlCommond);
                LoggerHelper.Info(msg);

                if (null != repository && !string.IsNullOrEmpty(sqlCommond))
                {
                    int? result = QueryEntitiesBySqlCommond<int?>(sqlCommond).FirstOrDefault();
                    if (result != null)
                    {
                        return Convert.ToInt32(result);
                    }
                }
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }
            
            return -1;
        } 


        /// <summary>
        ///     Create entity
        /// </summary>
        /// <param name="entity">entity</param>
        public void CreateEntity<T>(T entity) where T : class
        {
            string startTime = LoggerHelper.StartEvent();

            try
            {
                if (null != repository && null != entity)
                {
                    repository.Insert(entity);
                }
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }
        }


        /// <summary>
        ///     Modify entity
        /// </summary>
        /// <param name="entity">entity</param>
        public void ModifyEntity<T>(T entity) where T : class
        {
            string startTime = LoggerHelper.StartEvent();

            try
            {
                if (null != repository && null != entity)
                {
                    repository.Update(entity);
                }
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }
        }

        /// <summary>
        ///     Remove entity
        /// </summary>
        /// <param name="entity">entity</param>
        public void RemoveEntity<T>(T entity) where T : class
        {
            string startTime = LoggerHelper.StartEvent();

            try
            {
                if (null != repository && null != entity)
                {
                    repository.Delete(entity);
                }
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }
        }


        /// <summary>
        ///     commit transaction
        /// </summary>
        /// <returns>Number of objects to be saved</returns>
        public int SaveChanges()
        {
            string startTime = LoggerHelper.StartEvent();

            var nums = 0;
            try
            {
                if (null != repository)
                {
                    nums = repository.SaveChanges();
                }
            }
            catch (Exception e)
            {
                LoggerHelper.Error(e);
                throw;
            }
            finally
            {
                LoggerHelper.EndEvent(startTime);
            }

            return nums;
        }

        public string ImportSuccess()
        {
            return ResourceHelper.GetRsByKey("Common_Result_ImprotEntitySuccessfully");
        }
        public string ImportUnSuccess()
        {
            return ResourceHelper.GetRsByKey("Common_Result_ImprotEntityUnsuccessfully");
        }
        public ExecutionResult CreateExecutionResult(string rowIndex,string message)
        {
            ExecutionResult er = new ExecutionResult();
            er.RowIndex = rowIndex;
            er.Message = message;
            return er;
        }
        
    }
}

 

附加Unity的代码:

1.

using System;
using System.Collections.Generic;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace Zhang.Test.ELUnityUtility
{
    public static class ELUnityUtility
    {
        public static T Resolve<T>() where T : class
        {
            return Resolve<T>(typeof (T)) as T;
        }

        public static object Resolve<T>(this Type type)
        {
            var attrs = type.GetCustomAttributes(typeof (UnityInjectionAttribute), true) as UnityInjectionAttribute[];
            if (attrs != null && attrs.Length > 0)
            {
                var attr = attrs[0];
                var unitySection = attr.GetUnityConfigurationSection();
                if (unitySection != null)
                {
                    var container = new UnityContainer().LoadConfiguration(unitySection,
                        string.IsNullOrEmpty(attr.Container) ? unitySection.Containers.Default.Name : attr.Container);
                    var obj = string.IsNullOrEmpty(attr.Name)
                        ? container.Resolve(type)
                        : container.Resolve(type, attr.Name);
                    if (obj != null)
                    {
                        var piabAtttr =
                            obj.GetType().GetCustomAttributes(typeof (ELPolicyinjectionAttribute), false) as
                                ELPolicyinjectionAttribute[];
                        if (piabAtttr.Length > 0)
                        {
                            obj = PolicyInjection.Wrap(type, obj);
                        }
                        return obj;
                    }
                }
            }
            return null;
        }

        public static IEnumerable<T> ResolveAll<T>() where T : class
        {
            return ResolveAll(typeof (T)) as IEnumerable<T>;
        }

        public static object ResolveAll(this Type type)
        {
            var attrs = type.GetCustomAttributes(typeof (UnityInjectionAttribute), true) as UnityInjectionAttribute[];
            if (attrs != null && attrs.Length > 0)
            {
                var attr = attrs[0];
                var unitySection = attr.GetUnityConfigurationSection();
                if (unitySection != null)
                {
                    var container = new UnityContainer().LoadConfiguration(unitySection,
                        string.IsNullOrEmpty(attr.Container) ? unitySection.Containers.Default.Name : attr.Container);
                    return container.ResolveAll(type);
                }
            }
            return null;
        }
    }
}

2.
using System;
using System.Configuration;
using System.IO;
using Microsoft.Practices.Unity.Configuration;

namespace Zhang.Test.ELUnityUtility
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
    public class UnityInjectionAttribute : Attribute
    {
        public UnityInjectionAttribute(string Container)
        {
            this.Container = Container;
        }

        public string Container { get; set; }
        public string ConfigFile { get; set; }
        public string Name { get; set; }

        public UnityConfigurationSection GetUnityConfigurationSection()
        {
            if (!string.IsNullOrEmpty(ConfigFile))
            {
                var fileMap = new ExeConfigurationFileMap
                {
                    ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigFile)
                };
                var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                return configuration == null
                    ? null
                    : configuration.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
            }

            return ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
        }
    }

    [AttributeUsage(AttributeTargets.Class)]
    public class ELPolicyinjectionAttribute : Attribute
    {
        public string Name { get; set; }
    }
}

  

posted @ 2017-10-31 09:36  wu9xia  阅读(538)  评论(0编辑  收藏  举报