惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
腾讯CDC
D
Docker
G
Google Developers Blog
D
DataBreaches.Net
雷峰网
雷峰网
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
The Cloudflare Blog
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
量子位
美团技术团队
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 一味

[翻译]实例:在Android调用WCF服务 基于LRU淘汰的高性能缓存 不是架构的架构之四:业务层的实现与自动代理 不是架构的架构之三:系统基础(2)主键选择和并发 不是架构的架构之二:系统基础(1) 不是架构的架构之一:总体思路 一道算法题 技术先行or业务先行 用了一年的键盘,记录下键盘磨损的状况 一个业务系统设计构想(一) 安装VS2008/.Net3.5/.Net3.0/.Net2.0sp1失败的解决办法 常用存储过程4(K310。3版本获取物流新单据的编码) 常用存储过程3(获取编码的上级编码和短编码) 常用存储过程2(获取编码级次) 常用存储过程1(获取字符串中的第一个数值) SQL Server中Rollup关键字使用技巧 Math.Round函数四舍五入的问题 SQL Server进程阻塞的检查和解决办法(转自好友Blog) 学习NHibernate的感悟和疑惑
不是架构的架构之五:业务层的实现与自动代理(补充)
一味 · 2011-01-25 · via 博客园 - 一味

在上一篇中,我们提到了通过spring.net的自动代理生成自动适应配置的业务层,也简单提到了自动代理实现的原理,但是,由于自动代理是一个比较复杂的机制,尤其对于没有架构设计经验的朋友来说,所以在今天的文章中,主要是分析spring.net的自动代理的原理,然后对我们实现的业务层做一些分析和总结。


我们再来回顾一下调用自动代理的代码:

public static T Get<T>(T instance) where T : class
{
    var p = new ProxyFactory(instance);
    p.AddAdvice(new AroundAdvise());
    return p.GetProxy() as T;
}

在方法中接收了一个泛型参数:业务对象的实例,这个业务对象当然必须是class,返回一个经过spring.net框架包装后的自动代理对象,这个自动代理对象类型仍然是T,显然这个对象和传入的对象看起来是一致的。

首先创建了一个代理工厂,我们预先将需要注入到业务对象的代码写到AroundAdvise类中,这里将AroundAdvise类添加到代理工厂,通过代理工厂获取到的业务对象,实际上是返回了一个继承了业务对象的代理对象。见下图。

image

在图中,我们传入的业务对象是UserBiz,而返回的是经过自动代理后生成的随机名称的对象。

在spring.net内部实际上是通过Emit生成的IL代码。事实上,通过CodeDom也可以实现相类似的功能,几年前我曾经实现过一个基于CodeDom的数据持久框架,性能比目前大多数ORM性能都要好得多,但是由于工作原因,没有将其做完善就放下了。在.net 3.5框架中,我们还可以使用lambda表达式来实现类似的功能,通过lambda表达式性能和Emit相近,但是复杂性远低于Emit。而在.net4.0框架中,还可以使用动态语言ironpython来实现。


我们来看看一段业务层的代码。

public class UserBiz
{
    public static UserBiz Instance { get; private set; }
    static UserBiz()
    {
        Instance=BizAutoWcfProxy.Get(new UserBiz());
    }
    private UserBiz() { }

    public virtual User GetFirst(string user,string pwd)
    {
        using (var db = Db.Get())
        {
            return User.Schema.QueryFirst(db, User.Schema.Name == user & User.Schema.Pwd == pwd);
        }
    }
}

这是一个用户业务类的代码,业务对象不需要继承任何对象,也不需要实现任何接口,但是我们在编写业务对象的时候,仍然要遵循一些约定:

1.隐藏构造函数。使用private定义的无参构造函数,避免在不熟悉的程序员直接去new这个业务对象。表现层调用业务层一律通过业务对象.Instance来得到。

2.业务层方法需要都是virtual定义。由于自动代理的缘故,在自动代理对象中需要自动重新实现所有的业务方法,所以业务方法需要是可覆盖的。

3.方法传入传出参数必须是可序列化的。

4.在业务层中不允许方法重载。这个是由于我们的设计所限,我们昨天提到,通过wcf调用的时候,传给服务端的仅仅是方法名称,如果重载了方法,可能会导致调用错误。

使用这个业务方法:

var user = UserBiz.Instance.GetFirst(username, encodePwd);


使用完全透明,在开发表现层时,完全不需要考虑应用环境的问题。