基于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这些方式实现 ...
随机推荐
- 必须掌握的八个cmd 命令
一,ping 它是用来检查网络是否通畅或者网络连接速度的命令.作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS命令,它 所利用的原理是这样的:网络上的机器都有唯一确定的I ...
- Deactivate .NET refector
8.5版本用注册机注册时手快成Standed版本,搞错......,能否Deactivated,发现要联网..... 接下来查找.net reflector 在位置%UserProfile%\AppD ...
- SQL Server COM 组件创建实例失败
SQL Server COM 组件创建实例失败 SQL2008数据库总会出现从 IClassFactory 为 CLSID 为 {17BCA6E8-A95D-497E-B2F9-AF6AA4759 ...
- Qt MainWindow结构
(图自:FinderCheng 的 Qt 学习之路(11): MainWindow)
- iOS复选框
这种按钮iOS没有原生效果. 可以靠按钮的不同点击状态来实现这个效果. 代码如下: _workBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [ ...
- 微信公众号开发之被逼学web服务端1-----使用SecureCRT连接Linux服务器
做Android的进新公司后安排做微信公众号开发,这基本是后台和前端的活都要由小白的我来做,这两天基本成鸭子了,被填的满满的,却还是不够,博文仅作记录,希望能给后来的小白一点参考吧 今天做的是如何配置 ...
- angular2 - content projection-
angular2中的内容映射: App.component: <my-day> <my-lucky> </my-lucky> </my-day> MyD ...
- JVM加载类的过程,双亲委派机制中的方法
JVM加载类的过程: 1)JVM中类的整个生命周期: 加载=>验证=>准备=>解析=>初始化=>使用=>卸载 1.1.加载 类的加载阶段,主要是获取定义此类的二进 ...
- Eclipse
001.自动注释 window--preferences--java--codeStyle--codeTemplate--comments //Types: /** *@author ${user} ...
- java中的反射,知道类名创建类,还可以设置私有属性的值
刚刚学到了反射,感觉反射的功能好强大,所以想写篇博客记录下自己的学习成果. 利用反射来创建对象. Class c1=Class.forName("test.Person");//通 ...