基于Autofac, Castle.DynamicProxy的动态WCF解决方案(原创)
本方案解决了下面3个主要的问题:
1、减少配置,为了避免每次新增service都需要去修改配置文件,包括服务器端跟各个客户端的。
2、能够使用函数重载,泛型函数,以及泛型类。
3、使项目能够快速地在wcf与直接调用dll之间切换。
整个解决方案分为四块内容:1、客户端,2、契约层,3、服务端,4、实现层
1、客户端:只能看到契约层,而看不到具体的实现;但也可以通过直接引用实现层,从而脱离wcf(需要修改工厂方法,也可以改进一下,通过配置文件来做这个事情,但这个不是本解决方案的重点,有兴趣的可以自己去实现)。
2、契约层:包含DTO对象模型跟各个服务接口
3、服务端:能看到契约层跟实现层
4、实现层:使用Autofac跟Castle.DynamicProxy进行IOC跟AOP(动态代理中的拦截器)
为解决第一个问题,早些年,已有人通过只暴露WCF的一个服务,而向该服务传递类名,函数名,参数数组来解决这一问题,但是用字符串在我看来实在是不太好,谁能保证自己在编码的时候不会把字符串给写错呢,而且万一需要更改服务名,vs的代码重构机制也处理不了字符串。所以我觉得利用接口,应该是最好的解决方案,但问题是谁又能在不知道具体的实现类的情况下,而针对接口凭空实例化出来一个对象呢。答案是有的,用Emit指令,不过Emit指令实在是有点难。此时我又想到了单元测试中常用的Rhino Mocks跟moq框架,便去查看了它们的源代码,我发现其中一个用的.net自带的真实代理(RealProxy),另外个用的是Castle.DynamicProxy,个人比较喜欢Castle.DynamicProxy,就用了它的CreateInterfaceProxyWithoutTarget,然后在自定义的拦截器中去调用实际的WCF服务,将返回回来的值设置给invocation.ReturnValue。
并且针对方法中的传引用的参数,进行了处理,使其能够对传引用的参数进行赋值。
下图为整个解决方案的结构:

测试的接口:
public interface IMyTest
{
int Test1();
void Test2();
int Test3(int value);
TestModel Test4(ref TestModel T);
void Test5(TestModel T);
void Test6(out int value);
void Test7(ref int value);
int Test8(int value = );
int Test9(int value1 = , int value2 = );
int Test10(params int[] values);
int Test11(ref List<int> lst);
int Test12(TestEnumModel m);
TestEnumModel Test13(TestEnumModel m);
T Test14<T>(T m);
string Test14<T>(T m, int value);
string Test14<T>(T m, string value);
string Test14<T>(T m, TestModel model);
}
IMyTest接口
public interface IMyTest2<T>
{
T Test(T aa);
}
IMyTest2泛型接口
DTO对象:
public class TestModel
{
public int A { get; set; }
} public class TestImpModel : TestModel
{
public string B { get; set; }
} public enum TestEnumModel
{
A = ,
B =
}
DTO对象们
具体实现:
internal class MyTest : IMyTest
{
public int Test1()
{
return ;
} public void Test2()
{ } public int Test3(int value)
{
return value + ;
} public TestModel Test4(ref TestModel T)
{
T.A = T.A + ;
return T;
} public void Test5(TestModel T)
{
T.A = T.A + ;
} public void Test6(out int value)
{
value = ;
} public void Test7(ref int value)
{
value++;
} public int Test8(int value = )
{
return value;
} public int Test9(int value1 = , int value2 = )
{
return value1 + value2;
} public int Test10(params int[] values)
{
return values.Sum();
} public int Test11(ref List<int> lst)
{
lst.Add();
return lst.Sum();
} public int Test12(TestEnumModel m)
{
return (int)m;
} public TestEnumModel Test13(TestEnumModel m)
{
return m;
} public T Test14<T>(T m)
{
return m;
} public string Test14<T>(T m, int value)
{
return m.ToString() + value.ToString();
} public string Test14<T>(T m, string value)
{
return m.ToString() + value;
} public string Test14<T>(T m, TestModel model)
{
model.A += ;
return m.ToString() + model.A.ToString();
}
}
实现了IMyTest的MyTest类
internal class MyTest2<T> : IMyTest2<T>
{
public T Test(T aa)
{
return aa;
}
}
实现了IMyTest2的MyTest2泛型类
测试用例:
[TestMethod]
public void TestMethod1()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test1());
} [TestMethod]
public void TestMethod2()
{
MyCreator.Create<IMyTest>().Test2();
} [TestMethod]
public void TestMethod3()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test3());
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test3());
} [TestMethod]
public void TestMethod4()
{
var tm = new TestModel() { A = };
var t = MyCreator.Create<IMyTest>().Test4(ref tm);
Assert.AreEqual(, t.A);
Assert.AreEqual(, tm.A);
} [TestMethod]
public void TestMethod5()
{
var t = new TestModel() { A = };
MyCreator.Create<IMyTest>().Test5(t);
Assert.AreEqual(, t.A);
} [TestMethod]
public void TestMethod6()
{
int i = ;
MyCreator.Create<IMyTest>().Test6(out i);
Assert.AreEqual(, i);
} [TestMethod]
public void TestMethod7()
{
int i = ;
MyCreator.Create<IMyTest>().Test7(ref i);
Assert.AreEqual(, i);
} [TestMethod]
public void TestMethod8()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test8());
} [TestMethod]
public void TestMethod9()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test9(value2: ));
} [TestMethod]
public void TestMethod10()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test10(, ));
} [TestMethod]
public void TestMethod11()
{
List<int> lst = new List<int>();
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test11(ref lst));
Assert.AreEqual(, lst.Count);
Assert.AreEqual(, lst[]);
} [TestMethod]
public void TestMethod12()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test12(TestEnumModel.B));
} [TestMethod]
public void TestMethod13()
{
Assert.AreEqual(TestEnumModel.B, MyCreator.Create<IMyTest>().Test13(TestEnumModel.B));
} [TestMethod]
public void TestMethod14()
{
Assert.AreEqual(TestEnumModel.B, MyCreator.Create<IMyTest>().Test14(TestEnumModel.B));
} [TestMethod]
public void TestMethod15()
{
Assert.AreEqual("B123", MyCreator.Create<IMyTest>().Test14(TestEnumModel.B, ));
} [TestMethod]
public void TestMethod16()
{
Assert.AreEqual("Baaaaa", MyCreator.Create<IMyTest>().Test14(TestEnumModel.B, "aaaaa"));
} [TestMethod]
public void TestMethod17()
{
TestImpModel m = new TestImpModel() { A = , B = "" };
Assert.AreEqual("B2", MyCreator.Create<IMyTest>().Test14(TestEnumModel.B, m));
Assert.AreEqual(, m.A);
Assert.AreEqual("", m.B);
} [TestMethod]
public void TestMethod18()
{
TestImpModel m = new TestImpModel() { A = , B = "" };
var n = MyCreator.Create<IMyTest2<TestImpModel>>().Test(m);
Assert.AreEqual(, n.A);
Assert.AreEqual("", n.B);
}
18个简单的测试用例
项目源代码:DynamicWCF.rar
基于Autofac, Castle.DynamicProxy的动态WCF解决方案(原创)的更多相关文章
- ASP.NET Core搭建多层网站架构【9.2-使用Castle.Core实现动态代理拦截器】
2020/01/31, ASP.NET Core 3.1, VS2019, Autofac.Extras.DynamicProxy 4.5.0, Castle.Core.AsyncIntercepto ...
- Castle.DynamicProxy Part 1: ClassProxy
1.Castle中代理对象的分类 总的来说,代理对象大概可以分为2大类: 1.继承类型的代理对象 一类是继承类型的代理类.即:有一个类A,它的代理类是B.B是继承自A的.调用代理类B中的方法时,可以通 ...
- .NET 通过 Autofac 和 DynamicProxy 实现AOP
什么是AOP?引用百度百科:AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.实现AOP主要由两 ...
- Autofac高级用法之动态代理
前言 Autofac的DynamicProxy来自老牌的Castle项目.DynamicProxy(以下称为动态代理)起作用主要是为我们的类生成一个代理类,这个代理类可以在我们调用原本类的方法之前,调 ...
- 【转】Autofac高级用法之动态代理
原文:http://www.cnblogs.com/stulzq/p/8547839.html 前言 Autofac的DynamicProxy来自老牌的Castle项目.DynamicProxy(以下 ...
- Castle DynamicProxy基本用法(AOP)
本文介绍AOP编程的基本概念.Castle DynamicProxy(DP)的基本用法,使用第三方扩展实现对异步(async)的支持,结合Autofac演示如何实现AOP编程. AOP 百科中关于AO ...
- 使用Castle DynamicProxy (AOP)
在本文中,我将引导您了解.NET环境中的面向方面编程(AOP)概念,以及如何使用Castle DynamicProxy创建和附加方面.在我们开始之前,让我快速介绍AOP和 IoC.如果您已经熟悉这些 ...
- WCF分布式开发步步为赢(2)自定义托管宿主WCF解决方案开发配置过程详解
上一节<WCF分布式框架基础概念>我们介绍了WCF服务的概念和通信框架模型,并给出了基于自定义托管服务的WCF程序的实现代码.考虑到WCF分布式开发项目中关于托管宿主服务配置和客户端添加引 ...
- [AOP系列]Autofac+Castle实现AOP事务
一.前言 最近公司新项目,需要搭架构进行开发,其中需要保证事务的一致性,经过一番查找,发现很多博文都是通过Spring.Net.Unity.PostSharp.Castle Windsor这些方式实现 ...
随机推荐
- Android中常见功能包描述
在Android中,各种包写成android.*的方式,重要包的描述如下所示:android.app :提供高层的程序模型.提供基本的运行环境android.content:包含各种的对设备上的数据进 ...
- Qt线程(4) 降低线程占用CPU
问题描述: 一般将计算量大的处理过程单独放置到一个单独的线程处理,因此很有可能你的处理过程需要while(1)或类似的操作. 也因此很有可能造成线程在处理时计算机CPU占用过高的情况. 解决办法: 降 ...
- 网络虚拟化中的 offload 技术:LSO/LRO、GSO/GRO、TSO/UFO、VXLAN
offload 现在,越来越多的网卡设备支持 offload 特性,来提升网络收/发性能.offload 是将本来该操作系统进行的一些数据包处理(如分片.重组等)放到网卡硬件中去做,降低系统 CPU ...
- 数据分析:中国高校更名历史 Python
上周领了新任务,做国内高校改名历史的统计,这个挺有意思,以下是我任务完成过程,和大家分享. 一. 数据收集 数据需求:目前已有高校校名,各高校改名历史记录 高校校名数据来源:尝试从高校排名网站(iPI ...
- python 自学 1 day
#!/usr/bin/env python #coding = utf-8 age_of_oldby = 56 user = "fyt" word = "fyt" ...
- web开发实战--弹出式富文本编辑器的实现思路和踩过的坑
前言: 和弟弟合作, 一起整了个智慧屋的小web站点, 里面包含了很多经典的智力和推理题. 其实该站点从技术层面来分析的话, 也算一个信息发布站点. 因此在该网站的后台运营中, 富文本的编辑器显得尤为 ...
- laypage
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%> < ...
- 使用java连接MySQL数据库
import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import com.mys ...
- jquery插件的引用和扩展应用
引入插件,引用的jquery吆喝开发插件的jquery版本一致,引用插件里面所用的图像img图片等,常用的jquery可以通过对其进行函数描述,直接调用,下例子就是改变特定的颜色,插件的使用是在仿网页 ...
- OSX下Python模块安装常见问题解决
he following error occurred while trying to add or remove files in theinstallation directory: [Errno ...