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

 using System;
using System.Linq;
using System.Linq.Expressions;
using Zhang.Test.ELUnityUtility; namespace Zhang.Test.IDataLayer
{
[UnityInjection("First", Name = "GenericRepository", ConfigFile = "Zhang.Test.exe.config")]
public interface IRepository
{
IQueryable<T> GetEntitiesByCondition<T>(Expression<Func<T, bool>> predicate = null) where T : class;
T GetEntityByCondition<T>(Expression<Func<T, bool>> predicate) where T : class;
T GetEntityByPK<T>(object key) where T : class;
IQueryable<T> GetEntitiesBySqlCommond<T>(String sqlCommond);
void Insert<T>(T entity) where T : class;
//void BatchInsert<T>(IEnumerable<T> entities);
void Update<T>(T entity) where T : class;
void Delete<T>(T entity) where T : class;
//void BatchDelete<T>(IEnumerable<T> entities);
int SaveChanges();
}
}

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 -;
} /// <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 = ;
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; }
}
}

  

05-08 08:00