实际项目中使用Postsharp
2010-01-20 18:00
483 查看
我现在的项目中使用了winform(.net2.0) + asp.net mvc(.net3.5) + sqlserver2000,Orm使用的是Castle的ActiveRecord。客户端与服务器端通信使用的是Ice,可以通过动态代理切换为webservice或者remoting或者直连本地。而在客户端中是不能直接访问实体类中的延迟加载字段的。你可以专门写个服务来查询这种字段,不过用起来有些麻烦。所以在这种场合使用Postsharp来把这个查询操作透明化非常合适,可以使客户端和服务器端操作实体的字段变得一致。Postsharp利用attribute来修饰需要静态织入的类、方法、属性或字段,对于以上需求可以使用OnFieldAccessAspect:
[AttributeUsage(AttributeTargets.Field, Inherited = false), Serializable]
public class LazyLoadAttribute : OnFieldAccessAspect
{}
通过实验发现如果使用AttributeTargets.Property是不能达到效果的。在重载函数OnGetValue(FieldAccessEventArgs eventArgs)中实现调用服务的代码。下面要解决的问题是在后台调用实体的字段时不需要调用查询服务,所以需要在OnGetValue方法中判断当前是运行在客户端还是服务器端。因为我不太喜欢读配置文件,所以使用了硬编码的方式:
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
if (asm.FullName.StartsWith("GTCA.GCF"))
{
//客户端运行
_Flag = true;
//加载访问查询服务工具
Assembly asm_lazy = AppDomain.CurrentDomain.Load("GTCA.GCF.LazyTool");
//查询接口
_LazyTool = asm_lazy.CreateInstance("GTCA.GCF.LazyTool.LazyTool") as ILazyTool;
break;
}
}
ILazyTool接口是为了使访问查询服务的具体实现可以很灵活:
public interface ILazyTool
{
object BelongsTo(Type entityType, Guid entityId, string propertyName);
object HasMany(Type entityType, Guid entityId, string propertyName);
}
后面要做的事就很简单了判断当前的字段是BelongTo的还是HasMany的,然后通过服务获取数据后赋值给该字段eventArgs.ExposedFieldValue = data。
现在代码写完了只要把[LazyLoad]写在需要的字段上就ok了不过这样不会起任何作用,因为还需要在编译期调用Postsharp的编译工具才能实现静态织入。如果你是直接安装Postsharp会在vs编译c#项目是自动调用Postsharp工具,不过这样不适合在团队开发中使用。因为每个开发人员都要安装Postsharp并且凡是引用了写有[LazyLoad]项目的项目都会在编译时调用一边Postsharp编译工具。向我们项目中Entity中使用了LazyLoad,而Entity项目被一大堆的其他项目引用这样在每次编译时就会很慢(其实是Postsharp编译工具慢)。因此我们还要做点手脚——只有客户端主程序编译时才去调用它。其实Postsharp就是利用MSBuild来在编译期做一些手脚所以我们只要简单修改csproj文件来引入Postsharp的编译工具就ok了。
<PropertyGroup>
<PostSharpDir>../../../reference/tools/PostSharp 1.5</PostSharpDir>
<ImportPostSharp>False</ImportPostSharp>
</PropertyGroup>
<Import Project="$(PostSharpDir)/PostSharp-1.5.targets" Condition=" '$(ImportPostSharp)' == 'True' AND Exists('$(PostSharpDir)/PostSharp-1.5.targets')" />
其中PostSharpDir是Postsharp相关dll所在的文件夹,ImportPostSharp是启用Postsharp编译工具的开关默认为关。然后在编译客户端主程序时使用MSBuild命令行来编译项目就行了。
%windir%/microsoft.net/framework/v2.0.50727/msbuild /t:rebuild /property:Configuration=Debug;ImportPostSharp=True
现在就可以卸载掉Postsharp了,你可以在自己的项目中尝试下Postsharp还是比较简单的。
[AttributeUsage(AttributeTargets.Field, Inherited = false), Serializable]
public class LazyLoadAttribute : OnFieldAccessAspect
{}
通过实验发现如果使用AttributeTargets.Property是不能达到效果的。在重载函数OnGetValue(FieldAccessEventArgs eventArgs)中实现调用服务的代码。下面要解决的问题是在后台调用实体的字段时不需要调用查询服务,所以需要在OnGetValue方法中判断当前是运行在客户端还是服务器端。因为我不太喜欢读配置文件,所以使用了硬编码的方式:
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
if (asm.FullName.StartsWith("GTCA.GCF"))
{
//客户端运行
_Flag = true;
//加载访问查询服务工具
Assembly asm_lazy = AppDomain.CurrentDomain.Load("GTCA.GCF.LazyTool");
//查询接口
_LazyTool = asm_lazy.CreateInstance("GTCA.GCF.LazyTool.LazyTool") as ILazyTool;
break;
}
}
ILazyTool接口是为了使访问查询服务的具体实现可以很灵活:
public interface ILazyTool
{
object BelongsTo(Type entityType, Guid entityId, string propertyName);
object HasMany(Type entityType, Guid entityId, string propertyName);
}
后面要做的事就很简单了判断当前的字段是BelongTo的还是HasMany的,然后通过服务获取数据后赋值给该字段eventArgs.ExposedFieldValue = data。
现在代码写完了只要把[LazyLoad]写在需要的字段上就ok了不过这样不会起任何作用,因为还需要在编译期调用Postsharp的编译工具才能实现静态织入。如果你是直接安装Postsharp会在vs编译c#项目是自动调用Postsharp工具,不过这样不适合在团队开发中使用。因为每个开发人员都要安装Postsharp并且凡是引用了写有[LazyLoad]项目的项目都会在编译时调用一边Postsharp编译工具。向我们项目中Entity中使用了LazyLoad,而Entity项目被一大堆的其他项目引用这样在每次编译时就会很慢(其实是Postsharp编译工具慢)。因此我们还要做点手脚——只有客户端主程序编译时才去调用它。其实Postsharp就是利用MSBuild来在编译期做一些手脚所以我们只要简单修改csproj文件来引入Postsharp的编译工具就ok了。
<PropertyGroup>
<PostSharpDir>../../../reference/tools/PostSharp 1.5</PostSharpDir>
<ImportPostSharp>False</ImportPostSharp>
</PropertyGroup>
<Import Project="$(PostSharpDir)/PostSharp-1.5.targets" Condition=" '$(ImportPostSharp)' == 'True' AND Exists('$(PostSharpDir)/PostSharp-1.5.targets')" />
其中PostSharpDir是Postsharp相关dll所在的文件夹,ImportPostSharp是启用Postsharp编译工具的开关默认为关。然后在编译客户端主程序时使用MSBuild命令行来编译项目就行了。
%windir%/microsoft.net/framework/v2.0.50727/msbuild /t:rebuild /property:Configuration=Debug;ImportPostSharp=True
现在就可以卸载掉Postsharp了,你可以在自己的项目中尝试下Postsharp还是比较简单的。
相关文章推荐
- WebApi系列~实际项目中如何使用HttpClient向web api发异步Get和Post请求并且参数于具体实体类型
- WebApi系列~实际项目中如何使用HttpClient向web api发异步Get和Post请求并且参数于具体实体类型
- Android 6.0 运行时权限 在实际商业项目中的使用
- Android学习笔记---27_网络通信之通过GET和POST方式提交参数给web应用,以及使用httpClient,来给web项目以post方式发送参数
- 如何使用SSH框架开发实际项目-开发规范
- 实际项目中常用的加密算法及使用场景
- 我为什么反对在实际项目中使用类似ext的js技术框架
- AOP 系列: 使用PostSharp在.NET平台上实现AOP
- 在实际项目中第一次使用单元测试总结
- 使用struts2实现数据库数据导出成word文档(项目当中实际用的)
- ueditor编辑器【实际项目使用】
- 使用开源项目Asynchttpclient的GET_POST访问网络,上传文件
- 对实际项目中的get请求中文乱码以及post请求中文乱码的解决方案
- Map String数组的使用(业务逻辑)---实际项目中的问题
- 学习用Node.js和Elasticsearch构建搜索引擎(6):实际项目中常用命令使用记录
- log4j在web项目中的实际使用与jboss冲突
- 使用PostSharp在.NET平台上实现AOP
- Git 在实际项目中的使用
- 安卓开发进阶之RxJava在实际项目中使用--第二篇
- 使用 TestNG 的新特性管理实际项目中的大量单元测试