使用.Net代理模式做类的增强-阿里云开发者社区

开发者社区> 非常老帅> 正文

使用.Net代理模式做类的增强

简介: 我们已经实现了用户注册功能,现在想增加日志记录功能。具体来讲就是在用户注册前后,分别输出一条日志。
+关注继续查看

我们已经实现了用户注册功能,现在想增加日志记录功能。具体来讲就是在用户注册前后,分别输出一条日志。我们当然可以修改原有的业务代码。

现在换个角度来问两个问题:
1. 团队开发中,我们很可能根本拿不到源代码,那又怎么去增加这个功能呢?
2. 这次需求是增加日志,以后再增加其他需求(比如异常处理),是不是仍然要改业务类呢?

总结一下:
我们要在不修改原有类业务代码的前提下,去做类的增强。我们的设计要符合面向对象的原则:对扩展开放,对修改封闭

都有哪些办法呢?我们尝试以下几种方法:


原有业务类

业务模型

namespace testAopByDecorator
{
    public class User
    {
        public string Name { get; set; }
        public int Id { get; set; }
    }
}

接口设计

namespace testAopByDecorator
{
    public interface IUserProcessor
    {
        void RegisterUser(User user);
    }
}

业务实现

using System;

namespace testAopByDecorator
{
    public class UserProcessor : IUserProcessor
    {
        public void RegisterUser(User user)
        {
            if (user == null)
            {
                return;
            }

            Console.WriteLine(string.Format("注册了一个用户{0}:{1}", user.Id, user.Name));
        }
    }
}

上层调用

using System;

namespace testAopByDecorator
{
    class Program
    {
        private static User user = new User { Id = 1, Name = "滇红" };

        static void Main(string[] args)
        {
            Register();
            Console.ReadKey();
        }

        private static void Register()
        {
            IUserProcessor processor = new UserProcessor();
            processor.RegisterUser(user);
        }
    }
}

使用.Net代理模式做类的增强

我们将使用.net提供的System.Runtime.Remoting.Proxies.RealProxy来对原有的类做业务增强。

using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

namespace testAopByProxy
{
    public class UserProcessorProxy : RealProxy
    {
        private IUserProcessor _processor;

        public UserProcessorProxy(IUserProcessor processor): base(typeof(IUserProcessor))
        {
            this._processor = processor;
        }

        public override IMessage Invoke(IMessage msg)
        {
            IMethodCallMessage callMessage = (IMethodCallMessage)msg;
            User user = callMessage.Args[0] as User;

            before(user);
            object returnValue = (IMethodReturnMessage)callMessage.MethodBase.Invoke(this._processor, callMessage.Args);
            after(user);

            return new ReturnMessage(returnValue, new object[0], 0, null, callMessage);
        }

        private void after(User user)
        {
            Console.WriteLine("注册用户后:" + user.Name);
        }

        private void before(User user)
        {
            Console.WriteLine("注册用户前:" + user.Name);
        }
    }
}

上层调用

using System;

namespace testAopByProxy
{
    class Program
    {
        private static User user = new User { Id = 1, Name = "滇红" };

        static void Main(string[] args)
        {
            RegisterAndLog();
            Console.ReadKey();
        }

        private static void RegisterAndLog()
        {
            IUserProcessor processor = new UserProcessor();
            IUserProcessor proxy = (IUserProcessor)new UserProcessorProxy(processor).GetTransparentProxy();//代理原有业务类
            proxy.RegisterUser(user);//遵守接口契约
        }
    }
}

对比一下扩展前后的业务展现
这里写图片描述

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
DevExpress ASP.NET 使用经验谈(3)-XPO对象的使用(使用指定数据连接)
原文:DevExpress ASP.NET 使用经验谈(3)-XPO对象的使用(使用指定数据连接) 首先,我们贴出上一节Users类XPO对象的保存代码,直接建立的XPO Session会话,因为没有与我们所期望的数据层建立绑定, 所以程序自动创建了一个Access数据库,作为默认数据库操作对象来使用,即程序目录下的DevConsole.vshost.mdb数据库文件。
909 0
C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较
原文:C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较 使用Task,await,async,异步执行事件(event),不阻塞UI线程和不跨线程执行UI更新   使用Task,await,async 的异步模式 去执行事件(event) 解决不阻塞UI线程和不夸跨线程执行UI更新报错的最佳实践,附加几种其他方式比较 由于是Winform代码和其他原因,本文章只做代码截图演示,不做界面UI展示,当然所有代码都会在截图展示。
3331 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10051 0
DevExpress ASP.NET 使用经验谈(1)-XPO模型的创建
原文:DevExpress ASP.NET 使用经验谈(1)-XPO模型的创建 这个系列通过一些简单例子循序渐进,介绍DevExpress ASP.NET控件的使用。先来介绍一下XPO的使用,安装的DevExpress版本为DXperienceUniversal-12.2.4,使用Visual Studio 2012+Sql Server2005。
966 0
分享录制的正则表达式入门、高阶以及使用 .NET 实现网络爬虫视频教程
我发布的「正则表达式入门以及高阶教程」,欢迎学习。 课程简介 正则表达式是软件开发必须掌握的一门语言,掌握后才能很好地理解到它的威力; 课程采用概念和实验操作 4/6 分隔,帮助大家理解概念后再使用大量的实例加深对概念的理解; 实例操作是对概念最好的理解,也是学习新语言最有效的办法; 在课程中也穿插着大量软件开发的技巧和大家分享; 应该是把晦涩的正则表达式讲解的最生动的课程; 掌握了正则表达式后,您一定会觉得这是一门最值得掌握的语言。
931 0
DevExpress ASP.NET 使用经验谈(4)-CriteriaOperator的使用
原文:DevExpress ASP.NET 使用经验谈(4)-CriteriaOperator的使用 上一节中,我们已经介绍了,使用CriteriaOperator表达式,获取对象数据。 CriteriaOperator criteria = CriteriaOperator.
1038 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13865 0
DevExpress ASP.NET 使用经验谈(5)-通过ASPxGridView实现CRUD操作
原文:DevExpress ASP.NET 使用经验谈(5)-通过ASPxGridView实现CRUD操作 这节,我们将通过使用DevExpress的ASPxGridView控件,实现对数据的CRUD操作。
1105 0
+关注
非常老帅
IT行业从业10+年
481
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载